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.
这道题并不复杂,可是我还是用了很久才做出来,因为有一个细节之前一直没有考虑清楚。思路:考虑最高位应该用什么数字,假设n=5,那么1XXX有4!= 24中可能,2XXX、3XXX、4XXX同理都有24种可能,所以如果k=100,第一位应该填 100 / 24 + 1 = 5。同理第二位填的数字可以从{1,2,3,4}中选出,如果100%24相比3!来说比较大的话,应该从{1,2,3,4}这里面比较大的数字里选,准确的说要按照除3!的结果决定。同理当候选数字全部被选完的时候就得到了所求的Kth排列。需要注意,每次 “ 相除+1 ” 的结果不能直接放在res后面,因为其实上面例子中的5的含义是候选数组中从小到大排第5小(第1大)的数字。
但是如果K = 5! = 120该怎么办?第一位不可能选择6的呀?!可是换个角度思考,第120个排列应该是54321,第一位应该依然是5,似乎这种用 100 / 24 得到位序的方法遇到了大问题。
代码如下,这里k--是关键,具体原因我暂时还没有想到一个好的方式能解释清楚,待续。
string getPermutation(int n, int k) {
vector<int> factorial(n+1, 1); // factorial table
vector<int> candidates(n, 0);
string res;
int i, fac = 1;
for (i = 1; i <= n; i++) {
fac *= i;
factorial[i] = fac;
candidates[i-1] = i;
}
k--;
for(i = 1; i <= n; i++){
int index = k / factorial[n-i];
res += (char)('0' + candidates[index]);
candidates.erase(candidates.begin() + index);
k -= index*factorial[n-i];
}
return res;
}