题意:

解题思路:

  1. 思路:
  2. 首先我们将所有排列按首位分组:
  3. 1 + (2, 3, 4的全排列)
  4. 2 + (1, 3, 4的全排列)
  5. 3 + (1, 2, 4的全排列)
  6. 4 + (2, 3, 4的全排列)
  7. 接下来我们确定第 k=14个排列在哪一组中。
  8. 每组的排列个数是 3! = 6个,所以第14个排列在第3组中,所以首位已经可以确定,是3
  9. 然后我们再将第3组的排列继续分组:
  10. 31 + (2, 4的全排列)
  11. 32 + (1, 4的全排列)
  12. 34 + (1, 2的全排列)
  13. 接下来我们判断第 k=14个排列在哪个小组中。
  14. 我们先求第14个排列在第三组中排第几,由于前两组每组有6个排列,所以第14个排列在第3组排第 1462=2
  15. 在第三组中每个小组的排列个数是 2! = 2个,所以第 k 个排列在第1个小组,所以可以确定它的第二位数字是1
  16. 31 + (2, 4的全排列) => 3124 3142
  17. 由于24的最大排列为2,所以12 + 2 = 14,所以答案是3142

PHP代码实现:

  1. class Solution {
  2. /**
  3. * @param Integer $n
  4. * @param Integer $k
  5. * @return String
  6. */
  7. function getPermutation($n, $k) {
  8. $fact = 1;
  9. $nums = [];
  10. for ($i = 0; $i < $n; $i++) {
  11. $nums[$i] = $i + 1;
  12. $fact *= $i + 1;
  13. }
  14. $k -= 1;
  15. $res = "";
  16. for ($i = 0; $i < $n; $i++) {
  17. $fact = floor($fact / ($n - $i));
  18. $index = floor($k / $fact);
  19. $res .= (string) $nums[$index];
  20. $k %= $fact;
  21. unset($nums[$index]);
  22. $nums = array_values($nums);
  23. }
  24. return $res;
  25. }
  26. }

GO代码实现:

  1. func getPermutation(n int, k int) string {
  2. // offset k
  3. k = k - 1
  4. // build stack of permutations and an array from 1 to n
  5. permStack := []int{}
  6. nums := []int{1}
  7. currentP := 1
  8. for i := 2; i <= n; i++ {
  9. nums = append(nums, i)
  10. permStack = append(permStack, currentP)
  11. currentP = currentP*i
  12. }
  13. // build result
  14. result := ""
  15. for len(nums) > 1 {
  16. // pop from stack
  17. perm := permStack[len(permStack)-1]
  18. permStack = permStack[:len(permStack)-1]
  19. // find index
  20. idx := k/perm
  21. // find next k
  22. k = k%perm
  23. // add num at index to result
  24. result = result + strconv.Itoa(nums[idx])
  25. // delete num at index
  26. copy(nums[idx:], nums[idx+1:])
  27. nums = nums[:len(nums)-1]
  28. }
  29. return result + strconv.Itoa(nums[0])
  30. }