• LeetCode(60) Permutation Sequence


    题目

    The set [1,2,3,…,n] contains a total of n! unique permutations.

    By listing and labeling all of the permutations in order,
    We get the following sequence (ie, for n = 3):

    “123”
    “132”
    “213”
    “231”
    “312”
    “321”
    Given n and k, return the kth permutation sequence.

    Note: Given n will be between 1 and 9 inclusive.

    分析

    首先想到的是,采用STL库中的标准算法next_permutation(),寻找第k个排列即可,可是提交结果为Time Limited Exceed,显然,必须寻找更优算法。

    借鉴了别人的思想,设计如下(原文博客):

    数学解法

    在n!个排列中,第一位的元素总是(n-1)!一组出现的,也就说如果p = k / (n-1)!,那么排列的最开始一个元素一定是nums[p]。

    假设有n个元素,第K个permutation是

    a1, a2, a3, ….. …, an

    那么a1是哪一个数字呢?

    那么这里,我们把a1去掉,那么剩下的permutation为

    a2, a3, …. …. an, 共计n-1个元素。 n-1个元素共有(n-1)!组排列,那么这里就可以知道

    设变量K1 = K

    a1 = K1 / (n-1)!

    同理,a2的值可以推导为

    a2 = K2 / (n-2)!

    K2 = K1 % (n-1)!
    …….

    a(n-1) = K(n-1) / 1!

    K(n-1) = K(n-2) /2!

    an = K(n-1)

    STL标准算法实现(Time Limited Exceed)

    class Solution {
    public:
        string getPermutation(int n, int k) {
            if (n <= 0 || k <= 0 || k > factorial(n))
                return "";
    
            vector<int> v;
            for (int i = 1; i <= n; i++)
                v.push_back(i);
    
            int index = 1;
            while (index < k && next_permutation(v.begin(), v.end()))
                index++;
    
            string str = "";
            for (int i = 0; i < n; i++)
                str += IntToStr(v[i]);
            str += '';
    
            return str;
    
        }
    
        string IntToStr(int n)
        {
            string str = "";
    
            while (n != 0)
            {
                str += (n % 10 + '0');
                n /= 10;
            }
    
            reverse(str.begin(), str.end());
    
            return str;
        }
    
        long factorial(int n)
        {
            if (n <= 1)
                return 1;
            else
                return n * factorial(n - 1);
        }
    };

    AC代码

    class Solution {
    public:
    
        string getPermutation(int n, int k) {
            vector<int> nums(n);
    
            int pCount = 1;
            for (int i = 0; i < n; ++i) {
                nums[i] = i + 1;
                pCount *= (i + 1);
            }
    
            k--;
            string res = "";
            for (int i = 0; i < n; i++) {
                pCount = pCount / (n - i);
                int selected = k / pCount;
                res += ('0' + nums[selected]);
    
                for (int j = selected; j < n - i - 1; j++)
                    nums[j] = nums[j + 1];
                k = k % pCount;
            }
            return res;
        }
    
    };

    GitHub测试程序源码

  • 相关阅读:
    垃圾回收算法(1)标记-清除
    golang的interface剖析
    库文件的使用
    linux loadavg详解(top cpu load)
    撰写的《大数据处理框架Apache Spark设计与实现》出版了
    VUE文件上传删除、图片上传删除、视频上传删除
    三元运算符
    VScode格式化后单引号变双引号解决办法
    VUE实现分页
    绝望!新手小白在VUE组件之间进行传值上浪费了很多时间~
  • 原文地址:https://www.cnblogs.com/shine-yr/p/5214879.html
Copyright © 2020-2023  润新知