题目:
The set [1,2,3,…,n] contains a total of n! unique permutations.
By listing and labeling all of the permutations in order, we get the following sequence for n = 3:
- “123”
- “132”
- “213”
- “231”
- “312”
- “321”
Given n and k, return the kth permutation sequence.
Note:
- Given n will be between 1 and 9 inclusive.
- Given k will be between 1 and n! inclusive.
Example 1:
Input: n = 3, k = 3
Output: “213”
Example 2:
Input: n = 4, k = 9
Output: “2314”
解答:
本题的解题思路可以结合一定的数学来简化解法。
假如 n=4,则会发现所有的排序中,以1开头的共有3!=6种可能,这6种可能中,其中以12开头的则有2!=2种可能。同理,若n=5,则以1(或2或3或4或5)开头的共有4!=24种可能。以此类推可以发现:
以n=4,k=15为例,共有可能排序:
1 + 对2,3,4的全排列 (3!个)
2 + 对1,3,4的全排列 (3!个)
3 + 对1,2,4的全排列 (3!个) → 32 + 对1,4的全排列(2!个) → 321 + 对4的全排列(1!个) → 3214
4 + 对1,2,3的全排列 (3!个)
确定第一个数:
k = k-1 = 14 (从0开始计数)
index = k / (n-1)! = 2,得到第15个数的第一位是3
更新 k = k - index*(n-1)! = 2
确定第二个数:
k = 2
index = k / (n-2)! = 1, 得到第15个数的第二位是2
更新 k = k - index*(n-2)! = 0
确定第三个数:
k = 0
index = k / (n-3)! = 0, 得到第15个数的第三位是1
更新 k = k - index*(n-3)! = 0
确定第四位:
k = 0
index = k / (n-4)! = 0, 得到第15个数的第四位是4
最终确定n=4时第15个数为3214
因此结合以上思路可得到解题思路:
- 用 list 表示 1~n 待排序的整数,用数组 factorial 存储n个整数的阶乘。(这种采用一次遍历就计算出所有阶乘并存储在数组中,直接从数组中读取的思路值得借鉴)
- 令 k=k-1,通过上面的思路逐位找到对应的数字,其中每次找到一个数字后都从 list 中移除,从而能找到最后一次循环时 index=0 时剩余的最后一个数
class Solution {
public String getPermutation(int n, int k) {
StringBuilder res = new StringBuilder();
List<Integer> list = new ArrayList<>();
int[] factorial = new int[n+1];
factorial[0] = 1;
int temp = 1;
//计算阶乘
for(int i=1; i<=n; i++) {
list.add(i);
temp *= i;
factorial[i] = temp;
}
k=k-1;
for(int i=n-1; i>=0; i--) {
int index = k/factorial[i];
res.append(list.get(index));
list.remove(index);
k -= index*factorial[i];
}
return res.toString();
}
}