The set [1,2,3,…,n]
contains a total ofn! 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.
注意:这个题目真的是自己写的,要相信自己,自信~
计算1,2,3,...n共n个数字的全排列中的第k个,方法一可以先计算出这n!个全排列,然后取出第k个。
但是也可以通过发现规律,找第k个排列的时候,没有必要对其前面所有的进行排列,只需要找其各个位置上的数字即可。
首先用数组fac[i]来表示i的阶乘,把待放到最后结果中的数字按照顺序存放到list中,count表示还剩下的数字个数。
对于所求的第k(k从1开始)个排列,
Step0: 首先判断count是否为1,位1则结束循环,跳到Step7;
Step1: 可以用(k-1)/fac[count-1]计算目前应该加入到结果中的数字在list中的下标为num。
Step2: 然后更新k的值为(k-1)%fac[count-1]+1。
Step3: count--;
Step4: 把list.get(num)合并到结果中;
Step5: 把list中下标为num的数字从list中移除。
Step6: 继续循环;
Step7: 把剩下的最后一个数字合并到最后结果中;
Step8: 返回最终的结果。
比如对于1,2,3,4排列的第18个序列。
用list保存1 2 3 4。初始化count = 4.
fac[5] = {1,1,2,6,24}
第一次进入循环:num = (18-1)/6 = 2;
所以第一次合并到结果中的数字为list.get(2) = 3;然后把下标为2的元素移除list,并且count--。更新k的值为6,
然后接着继续循环得到了合并到结果中数字为4,2,直到list中只剩下一个数字,1合并到结果中,这样我们就得到了最后的结果为3421.
public String getPermutation(int n, int k)
{
if(n == 0){
return "";
}
/*fac[i]存放的是i的阶乘*/
int[] fac = new int[n+1];
factorial(fac,n+1);
/*list中存放待放到结果中的数字*/
List<Integer> list = new ArrayList<Integer>();
for (int i = 1; i <= n;i++)
{
list.add(i);
}
int count = list.size();//count表示剩下待加入到结果中的数字个数
/*循环计算把该放入到结果中的数字先存到sb中*/
StringBuilder sb = new StringBuilder();
while(count!=1){
int num = (k-1) / fac[count-1];
k = (k-1) % fac[count-1]+1;
sb.append(list.get(num));
list.remove(num);
count--;
}
sb.append(list.get(0));
return sb.toString();
}
/*计算小于等于n的所有整数的阶乘*/
public void factorial(int[] fac,int n){
fac[0] = 1;
for (int i = 1; i < n;i++ )
{
fac[i] = fac[i - 1] * i;
}
}