LeetCode 第 60 题排列序列

1,436 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第24天,点击查看活动详情

题目

排列序列

给出集合 [1,2,3,...,n],其所有元素共有 n! 种排列。

按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

"123"
"132"
"213"
"231"
"312"
"321"

给定 n 和 k,返回第 k 个排列。

 

示例 1:

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

示例 2:

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

示例 3:

输入:n = 3, k = 1
输出:"123"

提示:

1 <= n <= 9
1 <= k <= n!

题解

解题分析

解题思路

  1. 根据题意可知,对于 n 个不同的元素(例如数 1, 2, ⋯, n),它们可以组成的排列总数目为 n^2。
  2. 其实我们就是求 n-1 个元素组成的排列中,排列中第 k 个值。
  3. 然后我们对值进行枚举,然后最后得到结果。(备注,具体的逻辑可以看看代码注释)

复杂度

  • 时间复杂度 O(N^2)
  • 空间复杂度 O(N)

解题代码

题解代码如下(代码中有详细的注释说明):

class Solution {
     public String getPermutation(int n, int k) {
        //  n 阶乘 映射集 0...n-1
        int[] factorial = new int[n];
        factorial[0] = 1;
        for (int i = 1; i < n; ++i) {
            factorial[i] = factorial[i - 1] * i;
        }

        // k 需要先自减一 原因:
        // 不妨设分子为 k,那么得到的公式可能是这样的:
        //     ai =  ⌊k / (n-1)!⌋ + 1
        // 尝试使用以上公式计算 a1:
        //     (1)当 k < (n-1)! 时,a1 = ⌊k / (n-1)!⌋ + 1 = 1,正确
        //     (2)当 k = (n-1)! 时,a1 = ⌊k / (n-1)!⌋ + 1 = 2,错误
        // 而使用 ai =  ⌊(k-1) / (n-1)!⌋ + 1 却能正确处理这种情况
        // 即:只是简洁了数学公式的使用,如果不自减一的话,需要应对多种情况
        --k;
        // 结果
        StringBuffer ans = new StringBuffer();
        // 所有的值为 1
        int[] valid = new int[n + 1];
        // 填充默认值
        Arrays.fill(valid, 1);
        // 排列中 依次取得的排列的数的个数 1个...n个
        for (int i = 1; i <= n; ++i) {
            // 此公式可算出上面的数对应的从 1...n 中哪个数 order  | n - i 为了对应 factorial 下标,获取剩余个数排列种类总数
            int order = k / factorial[n - i] + 1;
            // 依次寻找对应的数 从 1...n
            for (int j = 1; j <= n; ++j) {
                // 找到一个数,若没有进入过结果排列集,减一,直至 order == 0 则表示找到该排列中的第 i 个数,修改标志集对应位置为已进入结果排序集
                order -= valid[j];
                if (order == 0) {
                    ans.append(j);
                    valid[j] = 0;
                    break;
                }
            }
            // 之后 k 对于已取得的数的排列位数取余,得到下一位需要的
            k %= factorial[n - i];
        }
        return ans.toString();
    }

}

提交后反馈结果如下:

image.png

参考信息