[LeetCode 60] Permutation Sequence
题目
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:
1. "123"
2. "132"
3. "213"
4. "231"
5. "312"
6. "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.
测试案例
Input: n = 3, k = 3
Output: "213"
Input: n = 4, k = 9
Output: "2314"
思路
已知以1开头的序列编号范围是:1 ~ (n - 1)!;以 2 开头的序列编号范围是:(n - 1)! + 1 ~ 2(n-1)! …… 以 p 开头的序列编号范围是: 1 + (p - 1)(n - 1)! ~ p(n - 1)!。从中可以发现,当待排序长度为 n 时:
\[ 开头数字的序号为 = (k - 1)/(n - 1)! + 1 \]
代码如下
class Solution {
public String getPermutation(int n, int k) {
int[] factor = new int[n];
factor[0] = 1;
for(int i = 1; i < n; i++){
factor[i] = factor[i - 1] * i;
}
int[] val = new int[n + 1];
for(int i = 1; i <= n; i++){
val[i] = i;
}
k--;
for(int i = 1, index; i <= n; i++){
index = k / factor[n - i] + i;
val[0] = val[index];
while(index > i){
val[index] = val[index - 1];
index--;
}
val[i] = val[0];
k %= factor[n - i];
if(k == 0){
break;
}
}
StringBuilder sb = new StringBuilder();
for(int i = 1; i <= n; i++){
sb.append(val[i]);
}
return sb.toString();
}
}
思路2
查询剩余字符中第 i 号字符时,可以采用平衡树存储。这样每次查找的时间复杂度为 \(O(lgn)\)。只是实现比较复杂。