zoukankan      html  css  js  c++  java
  • [LeetCode] 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.

    分析:首先想到的是回溯法的排列树+计数,但是排列树并不符合next_permutation 的关系,所以只能使用时间复杂度O(n^n)的排序树。。每个位置都有n中可能,记录下已经使用的数字,然后从未使用的数据中选择,然后递归调用,其实使用的还是回溯法的框架,有所更改。

    上Code,但是大数时会超时。。

     1 class Solution {
     2         vector<bool> m_avaliable;
     3         int m_k;
     4         int m_cnt;
     5         vector<int> m_array;
     6     public:
     7         string m_str;
     8 
     9         void dfs_permutation(int size, int dep)
    10         {
    11             if(dep == size)
    12             {
    13                 m_cnt ++;
    14                 if(m_cnt == m_k)
    15                 {
    16                     for(int i = 0; i < size; i++)
    17                     {
    18                         m_str += m_array[i] + '1';
    19                     }
    20                     return;
    21                 }
    22             }
    23 
    24             //dfs to the next level
    25             // every level has size choices, its time complexity is O(n^n)
    26             for(int i = 0; i < size; i++)
    27             {
    28                 if( m_avaliable[i] == true)
    29                 {
    30                     //cout <<"dep = " <<dep <<endl;
    31                     //cout <<"i   = " <<i <<endl;
    32                     m_array[dep] = i;
    33                     m_avaliable[i] = false;
    34                     dfs_permutation( size, dep+1);
    35                     m_avaliable[i] = true;
    36                 }
    37 
    38             }
    39 
    40 
    41 
    42         }
    43         string getPermutation(int n, int k)
    44         {
    45             //initinalize the member variable
    46             m_avaliable.resize(n, true);
    47             m_array.resize(n);
    48             m_k = k;
    49             m_cnt = 0;
    50             m_str.clear();
    51 
    52             //call dfs
    53             dfs_permutation(n, 0);
    54 
    55             // return 
    56             return m_str;
    57         }
    58 
    59 };

     方法二:基于 next permutation的方法的计算,复杂度O(n),不会超时,空间复杂度O(1)

     1 class Solution {
     2     public:
     3         string getPermutation(int n, int k)  
     4         {   
     5             k--;
     6 
     7             string s;
     8             vector<int> container;
     9             vector<int> res;
    10 
    11             for(int i = 1; i <=n; i++)
    12             {   
    13                 container.push_back(i);
    14             }   
    15             //printVector(container);
    16 
    17             for(int i = n-1; i >=0; i--)
    18             {   
    19                 int index = k/calcFactorial(i);
    20                 int value =  container[index];
    21                 res.push_back(value);
    22 
    23 
    24                 vector<int>::iterator findit = find(container.begin(),container.end(),value);
    25                 container.erase(findit);
    26                 k = k%calcFactorial(i);
    27 #if 0
    28                 cout << "===================================" <<endl;
    29                 cout << "i =	" << i <<endl;
    30                 cout << "index =	" << index <<endl;
    31                 printVector(container);
    32                 printVector(res);
    33                 cout << "===================================" <<endl;
    34 #endif
    35             }
    36             //printVector(res);
    37 
    38             for(int i = 0; i <res.size(); i++)
    39             {
    40                 s += res[i] + '0';
    41             }
    42             return s;
    43         }
    44 
    45         int calcFactorial(int n)
    46         {
    47             if(n == 0 || n == 1)
    48                 return 1;
    49             int sum = 1;
    50             for(int i = 2; i <= n; i++)
    51                 sum *= i;
    52             return sum;
    53         }
    54 
    55 };
  • 相关阅读:
    luogu 1865 数论 线性素数筛法
    洛谷 2921 记忆化搜索 tarjan 基环外向树
    洛谷 1052 dp 状态压缩
    洛谷 1156 dp
    洛谷 1063 dp 区间dp
    洛谷 2409 dp 月赛题目
    洛谷1199 简单博弈 贪心
    洛谷1417 烹调方案 dp 贪心
    洛谷1387 二维dp 不是特别简略的题解 智商题
    2016 10 28考试 dp 乱搞 树状数组
  • 原文地址:https://www.cnblogs.com/diegodu/p/3806603.html
Copyright © 2011-2022 走看看