Leetcode60. 第k个排列

Leetcode60. 第k个排列

题目:
给出集合 [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"

题解:
复杂度分析:

  • 时间复杂度: O ( N 2 ) \mathcal{O}(N^2) O(N2),从列表中删除元素,共执行操作次数: N + ( N − 1 ) + . . . + 1 = N ( N − 1 ) / 2 N + (N - 1) + ... + 1 =N(N - 1)/2 N+(N1)+...+1=N(N1)/2
  • 空间复杂度: O ( N ) \mathcal{O}(N) O(N)

首先构造 k = 2 k = 2 k=2 的阶乘数:

k = 2 = 1 × 2 ! + 0 × 1 ! + 0 × 0 ! = ( 1 , 0 , 0 ) k = 2 = 1 \times 2! + 0 \times 1! + 0 \times 0! = (1, 0, 0) k=2=1×2!+0×1!+0×0!=(1,0,0)

阶乘中的系数表示输入数组中,除去已使用元素的索引。这符合每个元素只能在排列中出现一次的要求。
在这里插入图片描述
第一个数字是 1,即排列中的第一个元素是 n u m s [ 1 ] = 2 nums[1] = 2 nums[1]=2。由于每个元素只能使用一次,则从 nums 中删除该元素。
在这里插入图片描述
阶乘中下一个系数为 0,即排列中 n u m s [ 0 ] = 1 nums[0] = 1 nums[0]=1,然后从 nums 中删除该元素。
在这里插入图片描述
阶乘中下一个系数也是 0,即排列中 n u m s [ 0 ] = 3 nums[0] = 3 nums[0]=3,然后从 nums 中删除该元素。
在这里插入图片描述

算法:

  1. 生成输入数组,存储从 1 1 1 N N N 的数字。
  2. 计算从 0 0 0 ( N − 1 ) ! (N - 1)! (N1)!的所有阶乘数。
  3. ( 0 , N ! − 1 ) (0,N!−1) (0,N!1) 区间内, k k k 重复减 1 1 1
  4. 计算 k的阶乘,使用阶乘系数构造排列。
  5. 返回排列字符串。

java代码:

/**
     * @param n
     * @param k
     * @return
     */
    public static String getPermutation(int n, int k) {

        int[] fact = new int[n];

        ArrayList<Integer> nums = new ArrayList<>();
        nums.add(1);
        fact[0] = 1;
        for (int i = 1; i < n; i++) {
            //fact存入0!,1!,2!...,(n-1)!
            fact[i] = fact[i - 1] * i;
            //nums 存入1,2,3,...,n
            nums.add(i + 1);
        }
        k = k - 1;
        StringBuffer str = new StringBuffer();
        for (int j = n - 1; j >= 0; j--) {
            int x = k / fact[j];
            k = k % fact[j];
            str.append(nums.get(x));
            nums.remove(x);
        }
        return str.toString();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值