[leetcode-JavaScript]60.第k個排列

題目

給出集合 [1,2,3,…,n],其全部元素共有 n! 種排列。 按大小順序列出全部排列狀況,並一一標記,當 n = 3 時, 全部排列以下:數組

"132"
"213"
"231"
"312"
"321"
複製代碼

給定 n 和 k,返回第 k 個排列。bash

說明:ui

給定 n 的範圍是 [1, 9]。 給定 k 的範圍是[1, n!]。 示例 1:spa

輸入: n = 3, k = 3
輸出: "213"
複製代碼

示例 2:code

輸入: n = 4, k = 9
輸出: "2314"
複製代碼

思路-以示例2爲例

  • 以1開頭的排列有3!個,第一個位置爲1,後面三個隨便排列,有1x2x3=6個
  • 以2開頭的排列有3!個,第一個位置爲2,後面三個隨便排列,有1x2x3=6個
  • 以3開頭的排列有3!個,第一個位置爲3,後面三個隨便排列,有1x2x3=6個
  • 以4開頭的排列有3!個,第一個位置爲4,後面三個隨便排列,有1x2x3=6個

因此第9個排列,第一個位置爲2排序

用這種方式繼續縮減數量,以2開頭的排序中最小爲[2,1,3,4],2已經固定,繼續找[1,3,4]的排列的第3個全排列,就是整個排列的第9個排列get

  • 以1開頭的有2!個,第一個位置爲1,後面隨便排列,有1x2=2個
  • 以3開頭的有2!個,第一個位置爲3,後面隨便排列,有1x2=2個
  • 以4開頭的有2!個,第一個位置爲4,後面隨便排列,有1x2=2個

因此第9個排列,第二個位置爲3string

用這種方式繼續縮減數量,以23開頭的排序中最小爲[2,3,1,4],23已經固定,繼續找[1,4]的排列的第1個全排列,就是整個排列的第9個排列io

  • 以1開頭的有1!個,第一個位置爲1,後面隨便排列,有1個
  • 以4開頭的有1!個,第一個位置爲4,後面隨便排列,有1個

因此第9個排列,第三個位置爲1function

因此結果爲2314

因此,能夠每次肯定一個大範圍,在大範圍的基礎上進一步縮小範圍,直到最後只有一個數字爲止。遍歷n遍便可。

代碼

/**
 * n!
 * @param {number} n
 * @return {number}
 */
var fact=function(n){
    if(n===0){
        return 1;
    }
    return fact(n-1)*n;
};
/**
 * 生成數組
 * @param {number} length
 * @return {Array}
 */
let f = length => Array.from({length}).map((v,k) => (k+1));
/**
 * @param {number} n
 * @param {number} k
 * @return {String}
 */
var getPermutation = function(n, k) {
    if(n<1){
        return;
    }
    let arr=f(n)
    let idx=0;
    let arrTemp=[];
    k=k-1;//注意 k 從 0 開始很重要,否則後邊整除和取餘很是很是繞
    while(k>0){
        let num=fact(n-idx-1);
        let index=parseInt(k/num);
        arrTemp.push(arr[index]);
        arr.splice(index, 1);
        idx++;
        k=k%num;
    }
    arrTemp=arrTemp.concat(arr)
    return arrTemp.join('');
    
};
複製代碼
相關文章
相關標籤/搜索