码迷,mamicode.com
首页 > 其他好文 > 详细

60. Permutation Sequence

时间:2016-05-13 23:19:00      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:

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]包含了总共n!个不同的排列。

列出并给所有的排列进行编号,可以得到一下序列(假设 n = 3):

1. "123"

2. "132"

3. "213"

4. "231"

5. "312"

6. "321"

给定 n 和 k ,求第 k 个排列。

备注: n 在 1 ~ 9 之间。

对于这个问题可以先考虑给出一个排列怎么求它是第几个排列,然后再从中逆推出第k个排列。要计算一个排列是第几个,只要算出它前面有多少个排列即可。假设n = 5,给出一个排列 35142,那么Nth(35142) = (3-1)*4! + Nth(4132),加号的前半段表示以小于3的1和2开头的排列各有4!个排列,加号右边计算以3开头的剩余有多少个排列。因为3的后面不能再用3了,所以这个问题就等价于求 4132 是第几个排列。如此递归的就可以得到最终结果。

假设 n = 5,令 m = 4!,根据这个计算过程,可以看到第k个排列的首位一定是 (k%m != 0)?(k/m+1):(k/m),剩余的数可以递归或者迭代计算。

每个数需要常数时间确定,所以整个算法时间复杂度是O(n)。给出算法如下:

string getPermutation(int n, int k) {
    vector<int> p(n+1, 1);
    for (int i=2; i<=n; ++i)
        p[i] = p[i-1] * i;
        
    vector<bool> used(n+1, false);
    string ret;
    for (int i=n; i>=1; --i)
    {
        int m = p[i-1];
        int t = (k%m != 0)?(k/m+1):(k/m);
        int j = 1;
        for (; j<=n; ++j)
        {
            if (!used[j])
            {
                --t;
                if (0==t)
                {
                    used[j] = true;
                    break;
                }
            }
        }
        
        ret.push_back(j+0);
        k = (k%m != 0)?k%m:m;
    }
    
    return ret;
}

 

60. Permutation Sequence

标签:

原文地址:http://www.cnblogs.com/zhiguoxu/p/5491408.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!