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 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.
- Given k will be between 1 and n! inclusive.
对n个数组成的数组进行升序排列,找出第k个
思路:
要找到第k个,首先确定第k个数组是从第几位数不再保持12345***这样的升序序列的。升序排列说明数组先变动后几位数字(如题目给出的n=3的情况,第二个数组是保持1不动,先变动后两位的位置),s个数有 s! 种排列方式,因此找出k小于且最接近几的阶乘,就找到了开始变化的位置。
Example 1:
Input: n = 3, k = 3
Output: "213"
如例1,k=3时,2! < k, 3! >k, 数组从倒数第三位开始变化。
Example 2:
Input: n = 4, k = 9 Output: "2314"
如例2,k=9时,3! < k, 4! >k,相对于1234,数组从倒数第四位开始变化。
好像解释的不太清楚,附上代码,有什么问题欢迎留言交流
class Solution {
public String getPermutation(int n, int k) {
int[] r = new int[n];
for (int i = 0; i < n; i++)
r[i] = i + 1;
r = repeat(r, k);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++)
sb.append(r[i]);
return sb.toString();
}
private int[] repeat(int[] r, int k){
if (k <= 1)
return r;
int neark = 0, s = 1, n = r.length;
for (int i = 1; i <= n; i++){
s *= i;
if (s >= k){
neark = i;
break;
}
}
int dif = n - neark, min = n-1;
for (int i = dif + 1; i < n; i++){
if (r[i] > r[dif])
min = r[min] < r[i]? min: i;
}
int tem = r[dif];
r[dif] = r[min];
r[min] = tem;
return repeat(r, k - (s/neark));
}
}