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.
同样是排列 组合的问题,这次不需要打印所有的排列了,只需要按照排列的顺序打印出第k个,很显然,思路不会是列出所有的排列,然后找第k个打印出来是吧。
观察来看,以1,2,3,4
为例,有4*3*2*1=24
种排列,其中根据排列的顺序,按照第一个数字可以分为以下4种:
1 * * *
2 * * *
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 * * *
#### 方法一
1+permutation(2,4)
2+permutation(1,4)
4+permutation(1,2)
k=k-index_pre*(n-1)!=13-2*3!=1
;
index=k/(n-2)!=1/(4-2)!=0
于是第二个数为1。
k=k-index_pre*(n-2)!=1-0*(4-2)!=1
, index=k/(n-3)!=1/(4-3)!=1
在此处表示为4.之后再确定最后一个:k=k-index_pre*(n-4)!=1-1*(4-4)=0
;
index=k/(n-4)!=0/(4-4)!=0
故第四个数为2到了这里,思路就比较清晰了。我们需要做的是从第一个一直到最后一个的循环,每次选出一个数,但是还需要将该数从原来的数组中剔除掉,因为前面选过的后面就不能排列了。
其实原理差不多,也还是根据排列的规律。只不过算的方法不一样。
class Solution {
public:
string getPermutation(int n, int k) {
if(n<=0)
return " ";
int i,j,f=1;
string s(n,'0');
for(i=1;i<=n;i++){
f*=i;
s[i-1]+=i;
}
for(i=0,k--;i<n;++i){
f/=n-i;
j=i+k/f;
char c=s[j];
for(;j>i;j--)
s[j]=s[j-1];
k%=f;
s[i]=c;
}
return s;
}
};