60.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package main
  2. func nextPermutationRune(runes []rune) {
  3. if len(runes) < 2 {
  4. return
  5. }
  6. var i int
  7. for i = len(runes) - 2; i >= 0; i-- {
  8. if runes[i] < runes[i+1] {
  9. break
  10. }
  11. }
  12. if i != -1 {
  13. var j int
  14. for j = i; j < len(runes)-1 && runes[j+1] > runes[i]; j++ {
  15. }
  16. runes[i], runes[j] = runes[j], runes[i]
  17. }
  18. for j, k := i+1, len(runes)-1; j < k; j, k = j+1, k-1 {
  19. runes[j], runes[k] = runes[k], runes[j]
  20. }
  21. }
  22. func getPermutationOld(n int, k int) string {
  23. res := make([]rune, 0)
  24. for i := 1; i <= n; i++ {
  25. res = append(res, rune('0'+i))
  26. }
  27. for i := 1; i < k; i++ {
  28. nextPermutationRune(res)
  29. }
  30. return string(res)
  31. }
  32. // (1 2 3 4) -> 4! permutaion
  33. // 1 (2 3 4) -> 3! permutaion
  34. // get 16th permutaion => 16 - 1 > 3! + 3!, so 3 (1 2 4)
  35. // => 15 - 3! - 3! = 3 > 2!, so 3 2 (1 4)
  36. // => 1, so 3 2 4 (1) => (append last candidate) 3 2 4 1
  37. func getPermutation(n int, k int) string {
  38. res := make([]byte, 0)
  39. candidate := make([]byte, 0)
  40. for i := 0; i < n; i++ {
  41. candidate = append(candidate, byte('1'+i))
  42. }
  43. // k: the No. of permutation
  44. // k--: steps left to next permutation
  45. k--
  46. for i, base := n-1, fact(n-1); i > 0; i-- {
  47. idx := k / base
  48. res = append(res, candidate[idx])
  49. candidate = append(candidate[:idx], candidate[idx+1:]...)
  50. k -= idx * base
  51. base /= i
  52. }
  53. res = append(res, candidate...)
  54. return string(res)
  55. }
  56. func fact(x int) int {
  57. if x <= 1 {
  58. return 1
  59. }
  60. return x * fact(x-1)
  61. }
  62. /* func main() {
  63. fmt.Println(getPermutationOld(4, 16))
  64. fmt.Println(getPermutation(4, 16))
  65. fmt.Println(getPermutation(1, 16))
  66. fmt.Println(getPermutation(0, 16))
  67. } */