1. 题目描述
给出集合 [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"
2. 解题思路
对于这道题目,我们可以找一些规律,然后再求解。
我们知道,n 个数字的排列一共有 n! 个,以 1 开头的排列有 (n-1)! 个,以 2、3…… n 为开头的也是(n-1)! 个。
以n = 4, k = 9为例,1234的排序如下:
我们要选的是第九个数字,每一组是六个数字,可以直接9 % 6 = 3 ,然后在第二组寻找第三个数组就可以了,也就是2314。
我们可以将它们看成不同的组。第 k 个排列落在哪个组,直接到那个组去找,大大缩小了寻找的范围。
这上面就是题目的大致思路了,下面就来看下具体解法。
我们可以先将1- 4 放在数组中:[1,2,3,4],索引 0 对应数字 1,有一个错位,所以我把 k 减 1 处理。
(9-1)/ 3! 取整等于索引1,对应数组中的2,就确定了第一个数为2。
现在就剩下三个数字,那就是在三个数字的全排列中按照上述方法继续寻找。
3. 代码实现
/*** @param {number} n* @param {number} k* @return {string}*/var getPermutation = function(n, k) {const nums = []let factorial = 1 // 阶乘的结果for(let i = 1; i <= n; i++){nums.push(i)factorial = factorial * i}k --let resStr = ''while(nums.length > 0){factorial = factorial / nums.lengthconst index = k / factorial | 0resStr += nums[index]nums.splice(index, 1)k = k % factorial}return resStr};
4. 提交结果

