来源:力扣
给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
“123”
“132”
“213”
“231”
“312”
“321”
给定 n 和 k,返回第 k 个排列
以k=3为例,观察数据我们可以分成这样三组数据
(1)“123” “132”
(2)“213” “231”
(3)“312” “321”
我们先确定k在哪一组,显然k应在第二组(3/2向上取整)
再分为两组(已经确定以2开头,此时k = k - 2 * 1 = 1)
(1)“13”
(2)“31”
k/1向上取整得1,要找的在第一组
了解过程以后我们需要寻找规律:(其实就是全排列)
- 每次分组,分的组数为当前可选数据长度(1,2,3),组内数据的个数,是剩余数据个数的阶乘(2!)
- 确定k在哪,可以逐层确定它在哪一组,(1) k = 3, k / 2! = 2,在第二组 (2) k = 3 - 1 * 2 = 1, k / 1! = 1, 在第一组
实现代码如下
/**
* @param {number} n
* @param {number} k
* @return {string}
*/
var getPermutation = function(n, k) {
k -= 1;
const factorial = new Array(n); //记阶乘的值
factorial[0] = 1;
for(let i = 1; i < n; i++){
factorial[i] =factorial[i-1] * i;
}
const nums = [];
//数位上可取的值
for(let i = 1; i <= n; i++){
nums.push(i);
}
let res = '';
for(let i = n - 1; i >= 0; i--){
let index = Math.floor(k / factorial[i]); /*确定k在第几组数据*/
res += nums[index];
nums.splice(index, 1);
k -= index * factorial[i];
}
return res;
};