[leetcode] 【数组】 60. Permutation Sequence

来源:互联网 发布:上海华东理工网络教育 编辑:程序博客网 时间:2024/04/28 16:32

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.

题意

和上一题31. Next Permutation 相似,这里给出的是n,一开始是按顺序排,然后一级级往下变大,求第k级的排列。
如n=3,其排列为:
“123”
“132”
“213”
“231”
“312”
“321”
k=3,则返回”213”。

题解

排法一个有n!种。
这里一种解法是从第一种排列开始,一级级按Next Permutation 的做法,循环k-1次.这种做法比较费时,每一轮都要耗时。

//cppclass Solution {public:    string getPermutation(int n, int k) {        string s(n, '0');        for (int i = 0; i < n; ++i)            s[i] += i+1;        for (int i = 0; i < k-1; ++i)            next_permutation(s.begin(), s.end());        return s;    }    template<typename BidiIt>    bool next_permutation(BidiIt first, BidiIt last)     {        //代码见上一题Next Permutation    }};

要是能直接判断k级哪一位是什么数,就比较快了。
这里涉及到 康托编码 的思路。
观察所有的排列,会发现第一个数的每一个都有(n-1)!种排列
如n=3,其排列为:
“123”
“132”
“213”
“231”
“312”
“321”
第一个数为1有2种,为2为3都有两种,所以第一个数的在原数组中的下标可以表示为 a1=(k-1)/(n-1)!,因为有(n-1)!种选择,所以下一个 k=k%(n-1-1)!

//cppclass Solution {public:    string getPermutation(int n, int k) {        string res(n,'1');        for(int i=0;i!=n;i++)            res[i]+=i;        return kth_permutation(res,k);    }    string kth_permutation(string s,int k)    {        int len =s.size();        int base=factorial(len-1);        string res;        string temp(s);        k--;        for(int i=len-1;i>0;k%=base,base/=i,i--)        {            char key=temp[k/base];            temp.erase(k/base,1);            res+=key;        }        res+=temp[0];        return res;    }    int factorial(int n)    {        int res=1;        for(int i=1;i<=n;i++)            res*=i;        return res;    }};
0 0
原创粉丝点击