[leetcode] Permutation Sequence

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.
 
动态规划:f(n)表示有n个数字时,全排列的个数。则:
  f(1) = 1;
  f(2) = 2 * f(1) = 2;
  f(3) = 3 * f(2) = 6;
  .
  .
  .
  f(n) = n * f(n-1);
 
分析:
给定n以及排列索引号k。可以得到第k个排列的字符串的倒数第n个位置上的字符为num[⌈k/f(n-1)⌉]。num数组为n个数的升序数组。
之后递归求解倒数第n-1个位置上的字符,此时
  n = n-1,
  k = k % f(n-1),当 k % f(n-1)不为0时,
  k = f(n-1),当k % f(n-1)等于0时。
同理,递归可以求解出待求序列所有位置上的字符。
 
举例说明:
输入4    6
初始化num[] = {0, 1, 2, 3, 4};
初始化待求序列 ret= “”;
(1)     n = 4, k = 6
  ⌈k/f(n-1)⌉ = ⌈6/f(3)⌉ = ⌈6/6⌉ = 1;
   所以,ret = ret + (‘0’ + num[1]) = “1”;
  移除该位置处的值,得到num = {0, 2, 3, 4}; 
  因为k % f(n-1) = 6 % 6 = 0, 所以k = f(n-1) = 6;
(2)     n = 3, k = 6;
  ⌈k/f(n-1)⌉ = ⌈6/f(2)⌉ = ⌈6/2⌉ = 3;
  所以,ret = ret + (‘0’ + num[3]) = “1” + “4” = “14”;
  移除该位置处的值,得到num = {0, 2, 3};
  因为k % f(n-1) = 6 % 2= 0, 所以k = f(n-1) = 2
(3)     n = 2, k = 2
  ⌈k/f(n-1)⌉ = ⌈2/f(1)⌉ = ⌈2/1⌉ = 2;  
  所以,ret = ret + (‘0’ + num[2]) = “14” + “3” = “143”;  
   移除该位置处的值,得到num = {0, 2};
  因为k % f(n-1) = 2 % 1= 0, 所以k = f(n-1) = 1
(4)     n = 1, k = 1;
  ⌈k/f(n-1)⌉ = ⌈1/f(2)⌉ = ⌈1/1⌉ = 1;
  所以,ret = ret + (‘0’ + num[1]) = “143” + “1” = “1432”;
  移除该位置处的值,得到num = {0};
  此时n – 1 < 1,停止递归。
 
所得待求序列为:1432。

验证:4的全排列为:
1234, 1243, 1324, 1342, 1423, 1432, … 4321。
即所得序列正确。
 
 1 class Solution
 2 {
 3 private:
 4   vector<int> num;
 5   string ret;
 6 
 7 private:
 8   int GetSequencesCount(int n)
 9   {
10     if(n == 0 || n < 0) return 0;
11     if(n == 1) return 1;
12     
13     return n * GetSequencesCount(n-1);
14   }
15 
16   void ConstructPermutation(int n, int k)
17   {
18     char ch = '0';
19     int sub_count = GetSequencesCount(n - 1);
20     int m = 1;
21     
22     if(sub_count != 0)
23     {
24       m = k / sub_count;
25       if(k % sub_count != 0) m += 1;
26       k = k % sub_count == 0 ? sub_count : k % sub_count;
27     }
28 
29     ch = '0' + num[m];
30     ret += ch;
31     num.erase(num.begin() + m);
32     
33     if(n > 1)
34       ConstructPermutation(n-1, k);
35   }
36 public:
37   string getPermutation(int n, int k)
38   {
39     ret = "";
40     num.clear();
41     for(int i = 0; i <= n; i++)
42       num.push_back(i);
43 
44     ConstructPermutation(n, k);
45     return ret;
46   }
47 };

 

posted @ 2015-02-02 14:26  imKirin  阅读(120)  评论(0编辑  收藏  举报