这题还有点意思,第一次提交是求的所有排列然后排序选择第k个,超时了,仔细一想确实有更好的方法,以4为例,可以先分四个区间,1*** 有6个,2***有6个,3***有6个,4***有6个,这样就可以根据k判断所在的区间在某个区间定位,这样其他的区间就不用判断了。定位到其中一个区间后,还可以用同样的方法递推下去,比如开始k为15,在第三个区间,第一个元素选3,把3从原来的数组中删除,之后就是从第3个区间里找第15-12==3个就是了,n为3时分为1**,2**,4**这些区间。知道最后n为1或2时,可以直接求解。
void recursive(vector<char> &num,string &ret,int n,int kth)
{
if (n==1)
{
ret +=num[0];
return ;
}
if (n==2)
{
if (kth==1)
{
ret += num[0];
ret += num[1];
return ;
}
else
{
if (kth==2)
{
ret += num[1];
ret += num[0];
return ;
}
else
return ;
}
}
int step = 1;
for(int i=1;i<n;i++)
step*=i;
if (kth>step*n)
return ;
int j = 1;
vector<char>::iterator iter = num.begin();
while(iter!=num.end()&&kth>j*step)
{
j++;
iter++;
}
if (iter==num.end())
return ;
ret += num[j-1];
num.erase(iter);
recursive(num,ret,n-1,kth-(j-1)*step);
}
string getPermutation(int n, int k) {
if(n==0||k==0)
return string("");
vector<char> num;
for(int i=1;i<=n;i++)
{
num.push_back(i+'0');
}
string ret="";
recursive(num,ret,n,k);
return ret;
}