美文网首页
011-第K个排列

011-第K个排列

作者: Woodlouse | 来源:发表于2020-05-16 19:39 被阅读0次

描述

一个序列[1, 2, 3, 4, ..., n]一共有n!个排列,写一个算法计算第k个排列;

分析

直观的方式是在上一题目中的解法基础上计算1-k-1的序列,以此推导出第k个序列的排列,这么做很浪费时间。

要使用时间复杂度的算法,需要了解康托展开,公式如下:

X = a_n*(n-1)! + a_(n-1)*(n-2)! + a_1*0!

康托展开是一个全排列和一个自然数的双射。

a_i是一个整数,0<=a_i<n,1<=i<=n;

a_i表示原数的第i位在当前未出现的元素中是排在第几个

以上公式是根据序列计算序列在全排列中的次序。

假设序列[a_1, a_2, .... a_n],如何计算a_1在第一个序列(1, 2, 3...n)中的位置呢?

a_1之后又n-1个元素,共有(n-1)!个排列,于是就知道:

  • a_1 = k/(n-1)!
  • k_2 = k%(n-1)!; a_2 = k_2/(n-2)!
  • a_n = 0

根据以上分析可以得出代码:

int factorial(int n) {
    int result = 1;
    for(int i=1; i<=n; i++) {
        result *= i;
    }
    
    return result;
}

vector<int> kthPermutation(const vector<int>&num, int k)
{
    int n = num.size();
    vector<int> S(num);
    vector<int> result;
    
    int base = factorial(n - 1);
    --k;
    
    for (int i=n-1; i>0; k%=base, base/=i, --i) {
        auto a = next(S.begin(), k/base);
        result.push_back(*a);
        S.erase(a);
    }
    
    result.push_back(S[0]);
    
    return result;
}

此算法的时间复杂度为O(n),空间复杂度为O(1)


代码在这儿

相关文章

  • 011-第K个排列

    描述 一个序列[1, 2, 3, 4, ..., n]一共有n!个排列,写一个算法计算第k个排列; 分析 直观的方...

  • 第k个排列

    https://leetcode-cn.com/explore/interview/card/bytedance/...

  • 输出数组的全排列

    思想: n 个元素数组全排列 = 第 1 个前缀 + 后 n - 1 个元素全排列 输出第 k 个元素之后的全排列...

  • 子集、全排列、第k个排列

    子集输出 全排列输出 存在重复数字的全排列 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。 按大...

  • 排列类算法问题大总结

    全排列 带重复元素的排列 下一个排列 上一个排列 第 k 个排列 排列序号 排列序号II 全排列 给定一个数字列表...

  • LeetCode:第k个排列

    第k个排列 题目叙述: 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。按大小顺序列出所有排列情况...

  • 60.第k个排列

  • 60. 第k个排列

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

  • 60. 第k个排列

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

  • [LeetCode]60、第K个排列

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

网友评论

      本文标题:011-第K个排列

      本文链接:https://www.haomeiwen.com/subject/exrwnhtx.html