60. Permutation Sequence

来源:互联网 发布:程序员女朋友礼物代码 编辑:程序博客网 时间:2024/06/07 01:42

Problem:

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.


这一题是要求给出[1,2,3,...,n],然后对其进行升序的全排列,然后给定一个k,求出第k项是哪个数。刚刚写完31题的求下一个序列,所以就马上有一个想法是给出初始序列1234...n然后再给出k,然后用next_permutation(vector<int>, int)来实现。但是我简单算了一下复杂度,最坏情况是n!次,最好是O(1),平均的话应该也差不多是O(n!),这个肯定是超时的。所以上网搜了一下关于全排列的算法,发现了完全合胃口的康拓展开:

X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0!

用例子来说明,假如一个序列 4321,比4小的有1,2,3这三个数,确定首位后,后面有3!种情况,所以有3*3!=18种。

然后看3,比3小有2个数,确定这位后,后面有2!种情况,所以有2*2!种,也就是4种。然后看2,比2小有1个,后面有1!种,也就是1种。看最后一位1,没有比它小的了,0种,所以比4321小的一共有18+4+1=23个。所以4321是第24小的数。

然后这道题可以用康拓的逆展开,也就是求第K项的。

以下例子摘自百度百科:

 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕
找出第96个数
首先用96-1得到95
用95去除4! 得到3余23
有3个数比它小的数是4
所以第一位是4
用23去除3! 得到3余5
有3个数比它小的数是4但4已经在之前出现过了所以第二位是5(4在之前出现过,所以实际比5小的数是3个)
用5去除2!得到2余1
有2个数比它小的数是3,第三位是3
用1去除1!得到1余0
有1个数比它小的数是2,第二位是2
最后一个数只能是1
所以这个数是45321


Code:(LeetCode运行9ms)

class Solution {public:    string getPermutation(int n, int k) {        string s = "";        for (int i = 1; i <= n; i++) {            s += ('0' + i);        }        return find_kth_permutation(s, k);    }    int factorial(int n) {        int result = 1;        for (int i = 1; i <= n; i++) {            result *= i;        }        return result;    }    string find_kth_permutation(string s, int k) {        int length = s.size();        string result = "";                int factor = factorial(length - 1);        k--;                for (int i = length - 1; i > 0; k %= factor, factor /= i, i--) {            //找有m个比k/factor小的数,就是要求序列的这一位。            auto tmp = next(s.begin(), k / factor);            result += *tmp;            s.erase(tmp);        }        result += s[0];        return result;    }};



原创粉丝点击