• [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 };
  • 相关阅读:
    洛谷 P1040 加分二叉树
    洛谷 P1892 团伙
    洛谷 P2024 食物链
    洛谷 P1196 银河英雄传说
    并查集--算法,优化,变种
    洛谷 P1801 黑匣子_NOI导刊2010提高(06)
    洛谷 P3370 【模板】字符串哈希
    洛谷 P1090 合并果子
    洛谷 P1219 八皇后
    线的缩放效果
  • 原文地址:https://www.cnblogs.com/lxd2502/p/4267719.html
Copyright © 2020-2023  润新知