• LeetCode60: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):

    1 “123”
    2 “132”
    3 “213”
    4 “231”
    5 “312”
    6 “321”
    Given n and k, return the kth permutation sequence.

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

    这道题最直观的的解法就是先求出全部的排列,然后再从结果中找到第k个值就可以。可是非常明显会超时。

    假设不能先将全部的排列都求出来,那么这道题的目的就是让我们直接找到第k个排列了。

    那么怎样找到第k个排列?直接要找到规律可能会比較困难,可是能够使用回溯和动态规划的一般方法,即使用用例来分析,从特殊到一般。看看通过这个特殊的用例能不能找到通用的方法,可是使用用例分析可能会因为用例选取的不全而导致遗漏一些情况,这道题做到最后就是用例选取的不全导致改了好久。

    取n=3,k=5,那么输出应该是第5个排列”312”。


    能够发现n=3时的全部排列中以1开头的排列有2个,以2开头的排列有2个,以3开头的排列有2个。
    排列的个数取决于后面的数有多少种排列,这里后面有2个数,排列的个数是2!=2。
    于是对于k=5能够这么分析
    5/2=2;
    5%2=1
    即将[123]第0位的数字1和第2位的数字3交换,第0位就处理好了,如今数组变成[321],接着指针移到到第1位。然后将第1位到最后的元素排序。数组变成了[312],然后求[12]中的第1个数。

    可是这样的求解方法会有一点问题,那就是本来5和6应该都是和第2位交换,可是因为6/2=3,结果变成了第0位和第3位交换,非常明显这是错误的,我们应该使用它在结果集中的下标来使用这个元素。对于k=5,实际上是第k-1=4个元素。对于4:
    4/2=2;
    4%2=0
    它表示第0个元素要和第2个元素交换,这时第0个元素就处理好了,然后再在后面的2个元素构成的排列中查询第4%2=0个元素,当全部的元素都处理好了以后,这个数组中的元素就是我们要找的第k个排列了。

    runtime:4ms

    class Solution {
    public:
        string getPermutation(int n, int k) {
            arr=new char[n];
            for(int i=0;i<n;i++)
                arr[i]=i+'1';
            helper(0,n,k-1);
            string str;
            for(int i=0;i<n;i++)
                str+=arr[i];
            return str;
        }
        void helper(int pos,int num,int k)
        {
            if(pos==num-1)
                return ;
            int base=k/fac(num-pos-1);
            int remain=k%fac(num-pos-1);
            sort(arr+pos,arr+num);
            swap(arr[pos],arr[pos+base]);
            helper(pos+1,num,remain);
        }
    
        int fac(int n)
        {
            int result=1;
            for(int i=1;i<=n;i++)
                result*=i;
            return result;
        }
        private:
        char *arr;
    };
  • 相关阅读:
    【PHP】算法: 获取满足给定值的最优组合
    @程序员,你还记得当年高考时的样子吗?
    教妹学 Java:难以驾驭的多线程
    二十九岁,刚读完了财富启蒙读物《小狗钱钱》
    蓦然回首,Java 已经 24 岁了!
    @程序员,你需要点金融常识
    教妹学 Java:大有可为的集合
    @程序员,你需要点财商
    教妹学 Java:晦涩难懂的泛型
    大量阅读,并不等同于“走马观花”
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7102435.html
Copyright © 2020-2023  润新知