目录:算法日记
题目来源:60. 排列序列
题目描述
给出集合 [1,2,3,...,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
"123""132""213""231""312""321"给定n和k,返回第k个排列。
题目示例
输入: n = 4, k = 9
输出: "2314"
数据范围
1 <= n <= 91 <= k <= n!
算法思路
先高位后低位,考虑每一位应该填什么。 以题目示例为例,当 时,先考虑第一位,有以下4种情况:
- 第一位为1,后接2,3,4的全排列,共 种可能;
- 第一位为2,后接1,3,4的全排列,共 种可能;
- 第一位为3,后接1,2,4的全排列,共 种可能;
- 第一位为4,后接1,2,3的全排列,共 种可能; 题目求第9个排列,第一位为1仅有6种排列,因此,第9个排列仅可能出现在以2为第一位的排列中,第一位确定为2。
按上述思路,分别确定每一位的数字,具体过程如下图所示,注意排列中的数字不重复。
AC代码
function getPermutation(n: number, k: number): string {
const vis: boolean[] = new Array(10).fill(false);
let res: string = "";
for(let i = 1; i <= n; i++) {
let cnt: number = 1;
for(let j = 1; j <= n - i; j++) cnt *= j;
for(let j = 1; j <= n; j++) {
if(vis[j]) continue;
if(k <= cnt) {
res += j.toString();
vis[j] = true;
break;
}
k -= cnt;
}
}
return res;
};