这个题要求全排列的第几个。
首先我们知道,A(n,m)=n!/(n-m)!,n个数的全排列是n!
要求全排列的第k个,采用构造法。
首先构造第一个数,第一个数的取值范围是1,2...n,然后定下来了第一个数,后面的数一共就有(n-1)!种可能。
看k真包含了几个(n-1)!(k>i*(n-1)!),就能确定第一个数是多少,例如n=3,k=4,(n-1)!=2,k真包含了1个(n-1)!(因为当i=2时,就不满足k>i*(n-1)!),所以第一个数是2。
以此类推,此时k=k-i*(n-1)!,k=2,k又真包含一个(n-2)!,所以第二个数是2。最后一个数恒定为1.
得到一个构造的序列221.这里每一位数字i代表【当前第i个没有用过的数字】
那么我们去找,第一个数字是2,1,2,3三个数字都没用过,所以第一个数是2.第二个数是2,去找1,2,3,发现1没用过,2用过,3没用过,第二个没用过的数是3,于是第二个数确定为3.第三个数字1,找第一个没用过的数字,是1,于是最后的序列就是231.
public class Solution {
public String getPermutation(int n, int k) {
char[] rst=new char[n];
String rst_s="";
if(n==0)
return rst_s;
int[] fac=new int[n];
int[] flag=new int[n];
fac[0]=1;flag[0]=0;
int i,j,l;
for(i=1;i<n;i++)
{
fac[i]=fac[i-1]*(i+1);
flag[i]=0;
}
for(j=0;j<n-1;j++)
{
for(i=1;i<n;i++)
{
if(k>i*fac[n-2-j])
continue;
else
break;
}
k=k-(i-1)*fac[n-2-j];
rst[j]=(char)(i+'0');
}
rst[j]=(char)('1');
for(i=0;i<n;i++)
{
l=0;
for(j=0;j<n;j++)
{
if(flag[j]==0)
l++;
if(l==(int)(rst[i]-'0'))
{
rst[i]=(char)(j+1+'0');
flag[j]=1;
break;
}
}
}
rst_s=String.valueOf(rst);
return rst_s;
}
}