leetcode 60. 第k个排列

题目:给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

给定 n 和 k,返回第 k 个排列。
说明:
给定 n 的范围是 [1, 9]。
给定 k 的范围是[1, n!]。

示例 1:

输入: n = 3, k = 3
输出: "213"

示例 2:

输入: n = 4, k = 9
输出: "2314"

基本思想: 第一位的值,由k包含几个(n-1)!决定
方法一:这个方法用了nums.splice,每删除一个元素,后面的元素都要往前移动,效率不高。执行用时战胜了35%。

/**
 * @param {number} n
 * @param {number} k
 * @return {string}
 */
var getPermutation = function(n, k) {
    // 定义一个数组,用于存放阶乘
    const f = []
    f[0] = 1
    for(let i=1; i<n; i++) {
        f[i] = i * f[i-1]
    }

    // 定义一个数组用于存放所有能选择的值
    const nums = []
    for(let i=1; i<=n; i++) {
        nums[i-1] = i
    }

    // 开始查找
    let res = ''
    k--  // 第 k 个,找为 k-1
    for(let i=n-1; i>=0; i--) {
        const index = Math.floor(k / f[i])
        res += nums[index]
        nums.splice(index, 1)
        k = k % f[i]
    }

    return res
};

方法二:不删除数组元素,只是标记一下数据是否被用了。执行用时战胜了85%

/**
* @param {number} n
* @param {number} k
* @return {string}
*/
var getPermutation = function(n, k) {
  // 定义一个数组,用于存放阶乘
  const f = [1]
  for(let i=1; i<n; i++) {
      f[i] = i * f[i-1]
  }

  // 定义一个数组用于存放所有能选择的值
  const nums = new Array(n).fill(false)

  // 开始查找
  let res = ''
  k--  // 第 k 个,找为 k-1
  for(let i=n-1; i>=0; i--) {
      // 查找的第几个还可以选的值
      const target = Math.floor(k / f[i]) + 1
      let count = 0
      for(let j=0; j<n; j++) {
          if(!nums[j]) {
              count++
          }
          if(target === count) {
              res += j+1
              nums[j] = true
              break
          }
      }
      
      k = k % f[i]
  }

  return res
};

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容