题目:
给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
“123”
“132”
“213”
“231”
“312”
“321”
给定 n 和 k,返回第 k 个排列。
说明:
给定 n 的范围是 [1, 9]。
给定 k 的范围是[1, n!]。
示例 1:
输入: n = 3, k = 3
输出: “213”
示例 2:
输入: n = 4, k = 9
输出: “2314”
分析:
重点是确定第k个每一位应该是什么,从前往后有规律,按照规律遍历到最后一位
代码:
public String getPermutation(int n, int k) {
int[] c = new int[n];
c[0] = 1;
for (int i = 1; i < n; i++) {
c[i] = i * c[i - 1];
}
StringBuffer sb = new StringBuffer();
boolean[] used = new boolean[n];
int index;
int temp = n - 1;
for (int i = 0; i < n; i++) {
// 获取该位应该获取的排序大小
index = k / c[temp];
if (k != index * c[temp]) {
index++;
}
// 找到数组里还没被使用的第index个数字,并使用他
sb.append(getAndUse(used, index));
k = k % c[temp];
if (k == 0) {
k = c[temp];
}
temp--;
}
return sb.toString();
}
private int getAndUse(boolean[] used, int index) {
int l = used.length;
int count = 0;
for (int i = 0; i < l; i++) {
if (!used[i]) {
count++;
}
if (count == index) {
used[i] = true;
return i + 1;
}
}
return 0;
}
效率:
总结:
需要标记已经使用的位置和找到全排列每一位的规律