60.go 1.6 KB

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