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 (ie, 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.
» Solve this problem
其实本题数据不大,n最多为9,9! = 362880,枚举应该能够通过(我没试验)。
我采用的方法是计算第k个Permutation。
假设n = 6,k = 400
先计算第一位,
第一位为6,那么它最少也是第5! * 5 + 1个排列,这是因为第一位为1/2/3/4/5时,都有5!个排列,因此第一位为6时,至少是第5! * 5 + 1个排列(这个排列为612345)。
5! * 5 + 1 = 601 > k,所以第一位不可能是6.
一个一个地枚举,直到第一位为4时才行,这时,4xxxxx至少为第5! * 3 + 1 = 361个排列。
然后计算第二位,
与计算第一位时的区别在于,46xxxx至少为第4! * 4 + 1 = 97个排列,这是因为比6小的只有5/3/2/1了。
最后可以计算出第二位为2。
最终得出第400个排列为425361。
根据这个思路,代码如下:
class Solution {
public:
string getPermutation(int n, int k) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int pow[n + 1];
pow[0] = 1, pow[1] = 1;
for (int i = 2; i <= n; i++) {
pow[i] = pow[i - 1] * i;
}
string ans;
bool selected[n + 1];
memset(selected, false, sizeof(bool) * (n + 1));
for (int i = n; i >= 1; i--) {
for (int j = n; j >= 1; j--) {
if (!selected[j]) {
int count = 0;
for (int q = 1; q <= n; q++) {
if (!selected[q] && q < j) {
count++;
}
}
if (pow[i - 1] * count < k) {
k -= pow[i - 1] * count;
ans += (char) (j + '0');
selected[j] = true;
break;
}
}
}
}
return ans;
}
};