问题描述
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.
思考:
1、序列123,排在第一位,其中,1在123中排第一位,2在23中排第一位,3在3中排第一位。
(1−1)∗2!+(1−1)∗1!+(1−1)∗0!=0
132,中1在123拍第一位,3在23中排第二位,2在2中排第一位。 (1−1)∗2!+(2−1)∗1!+(1−1)∗0!=1
213中…. (2−1)∗2!+(1−1)∗1!+(1−1)∗0!=2取A[i]表示result中第i个数在i到n 的大小排序(序号从0开始),则有k-1 = (n-1)! * A[0] + (n-2)! * A[1]…..1! * A[n-2] + 0! * A[n-1]$;其中,A[n - 1] 表示n到n的排序,因为只有一个数,所以A[n - 1]的序号为0;如k=3,result为213 :A[0..3] = 100,即(2在123中排序第2,1在13中排序第1,3在3中排序第1) 3 - 1 = 1 * 2!= 2。
从A[0..n]推导result过程中,因为序号为A[n]从零开始,但是其排序位置为1, 即A[i]表示排序大小为k的数,则A[i]=k-1.所以,result[i] = A[i] + 1; 在确定result[i]之后,从i+1到n中,因为i..n中result[i],排k位,所以对i..n。 中每一位result[m] >= result[i],都使reslut[m]++;(如果后面的result = result[i],则在第i位计算排序时,第m位必定高于第i位,所以,让reuslt[m]++) 如213中,从后往前看,当计算到1时,1在13中排第一位(此时,result为011),所以让3那个位置+1,变为012,计算2时,2的排位应该为2(在123中),所以2的 reslut为2,然后往后看,此时result为(212),然后让3那个位置加1变为213, 即为正确的结果。(类似与在已排好序的数组中在插入第k个数,然后调整排序)
2、对于 k−1=(n−1)!∗A[0]+(n−2)!∗A[1].....1!∗A[n−2]+0!∗A[n−1] ; 第一位数为为(1..n)中的第k / (n - 1)!位,第二位数为(1..n)中除去第一位的第 k′ / (n - 2)位。其中, k′ = k% (n-1)! 以此类推。
代码
第一种:
public class Solution {
public String getPermutation(int n, int k) {
k--;
char[] result = new char[n];
result[n - 1] = '1'; //n-1 表示A[n - 1],肯定在第一位
int factorial = 1;
for(int i = 2; i < n + 1; i++){
factorial *= i ;
result[n - i] = (char)(k % factorial * i / factorial
+ '1'); //表示reslut[n - i]中有多少个(i-1)!
for(int j = n - i + 1; j < n; j++)
result[j] += result[n - i] > result[j]? 0: 1;
k -= k % factorial;
}
return new String(result);
}
}
第二种
public class Solution {
public String getPermutation(int n, int k) {
List<Integer> list = new LinkedList<Integer>();
for(int i = 0; i < 9; i++)
list.add(i + 1);
k--;
int fact = 1;
for(int i = 2 ; i <= n; i++)
fact *= i;
StringBuffer sb = new StringBuffer();
for(int i = n ; i > 0; i--){
fact /= i;
sb.append(list.remove(k / fact));
k %= fact;
}
return sb.toString();
}
}