Permutation Sequence

来源:互联网 发布:java linux 绝对路径 编辑:程序博客网 时间:2024/05/22 01:30

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. 首先构造出来一个1 - n 的字符序列 p
2. 算出k的阶乘是多少 div
3. 如果k >= div ,那就是返回整个反转的p
4. 开始以下循环:
   div /= i; 
    pos = (k - 1) / div;
   这两行代码计算得到了pos,可以想一下,这时pos的含义是(k - 1)是div的多少倍, 只有经历一次完整的div变换,才能使得最高位换上一个新数, 现在经历了pos次,那么就是说第pos的字符被换到了当前最高位。
   k -= (pos * div) 
   得到还剩下多少个计数没有被处理
   p.erase(p.begin() + pos);
   因为地pos的元素已经知道会被放到当前最高位(ret当前的末尾),再下个循环处理k的时候这个元素已经不存在了,所以要剔除它。

在纸上画一遍1,2,3,4 第10个序列的过程会对这个过程有直观的理解。

1,2,3,4  (n = 4, k = 10)

第一次循环 
div /= 4   -> div = 6
pos = (k - 1) / 6  -> pos = 1
k -= (pos * div) -> k = 4
把2 放入 ret,从p剔除2

1,3,4     (ret = "2")

第二次循环:
div /= 3   -> div = 2
pos = (k - 1) / 2  -> pos = 1
k -= (pos * div) -> k = 2
把3 放入 ret,从p剔除3

1,4     (ret = "2 3")

第三次循环:
div /= 2   -> div = 1
pos = (k - 1) / 2  -> pos = 1
k -= (pos * div) -> k = 1
把4 放入 ret,从p剔除1

1 (ret= "2 3 4")

第四次循环:
div /= 1  -> div = 1
pos = (k - 1) / 1  -> pos = 0
k -= (pos * div) -> k = 1
把1 放入 ret,从p剔除1

ret = "2341"

从 “1234” 到 “2341“ ,k = 10

1234 -〉2134 ,消耗6次变换
2134 -> 2314, 消耗2次变换
2314-> 2341, 消耗1次变换

共消耗9次变换,位置从第一个变成第10个,这正是k= 10的要求。


class Solution {public:    string getPermutation(int n, int k) {        // IMPORTANT: Please reset any member data you declared, as        // the same Solution instance will be reused for each test case.        if (k < 1) throw k;        int div = 1;        string p(n, '0');        for (int i = 1; i <= n; i++) {            p[i - 1] += i;            div *= i;        }                        if (k >= div) {            reverse(p.begin(), p.end());            return p;        }                string ret(n, ' ');        auto rit = ret.begin();        for (int i = n; i > 0; --i) {            div /= i;            int pos = (k - 1) / div;            k -= (pos * div);            *rit++ = p[pos];            p.erase(p.begin() + pos);        }        return ret;    }};    


0 0
原创粉丝点击