博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LeetCode:Permutation Sequence
阅读量:7088 次
发布时间:2019-06-28

本文共 2465 字,大约阅读时间需要 8 分钟。

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.


 

在面试时需要注意咨询面试官,输入的k 是否小于1 或者 是否大于n!

分析:按照一般的递归求全排列的算法(),输出的序列不是按字典序有序的,比如对于1,2,3,输出序列为:

1 2 3

1 3 2
2 1 3
2 3 1
3 2 1
3 1 2

以3开头的排列举例,算法中是把1和3交换得到3 2 1,然后递归的求解,但是3 2 1不是以3开头的最小序列,应该是3 1 2. 为了得到有序的序列,我们不是把1 3 交换,而是应该把3移动到1的前面,这样得到的第一个以3开头的序列就是3 1 2。因此有如下的算法:

算法1

 
View Code

该算法在大数据下超时了。


 

算法2

利用next_permutation函数(该函数的详解请参考算法3),这种做法也超时了

 
View Code

算法3                                                 

上面的算法都是逐个的求排列,有没有什么方法不是逐个求,而是直接构造出第k个排列呢?我们以n = 4,k = 17为例,数组src = [1,2,3,...,n]。

第17个排列的第一个数是什么呢:我们知道以某个数固定开头的排列个数 = (n-1)! = 3! = 6, 即以1和2开头的排列总共6*2 = 12个,12 < 17, 因此第17个排列的第一个数不可能是1或者2,6*3 > 17, 因此第17个排列的第一个数是3。即第17个排列的第一个数是原数组(原数组递增有序)的第m = upper(17/6) = 3(upper表示向上取整)个数。                                           

第一个数固定后,我们从src数组中删除该数,那么就相当于在当前src的基础上求第k - (m-1)*(n-1)! = 17 - 2*6 = 5个排列,因此可以递归的求解该问题。

1 class Solution { 2 public: 3     string getPermutation(int n, int k) { 4         string str = string("123456789").substr(0, n); 5         string res(n, ' '); 6         for(int i = 0; i < n; i++) 7             res[i] = helper(str, k); 8         return res; 9     }10     //以s中字符构造的全排列中,返回第k个排列的第一个字符,并且删除s中该字符11     //s中字符递增有序12     char helper(string &s, int &k)13     {14         int tmp = factorial(s.size()-1), i = (k-1)/tmp;15         char res = s[i];16         s.erase(i, 1);17         k -= i*tmp;//更新k18         return res;19     }20     //求正整数n的阶乘21     int factorial(int n)22     {23         int res = 1;24         for(int i = 2; i <= n; i++)25             res *= i;26         return res;27     }28 };

当然也可以非递归实现

1 class Solution { 2 public: 3     string getPermutation(int n, int k) { 4         int total = factorial(n); 5         string candidate = string("123456789").substr(0, n); 6         string res(n,' '); 7         for(int i = 0; i < n; i++)//依次计算排列的每个位 8         { 9             total /= (n-i);10             int index = (k-1) / total;11             res[i] = candidate[index];12             candidate.erase(index, 1);13             k -= index*total;14         }15         return res;16     }17     int factorial(int n)18     {19         int res = 1;20         for(int i = 2; i <= n; i++)21             res *= i;22         return res;23     }24 };

 

本文转自tenos博客园博客,原文链接:http://www.cnblogs.com/TenosDoIt/p/3721918.html,如需转载请自行联系原作者
你可能感兴趣的文章
DKhadoop安装配置步骤教程与常见问题解决
查看>>
独家揭秘!阿里大规模数据中心的性能分析
查看>>
5.DI的配置使用
查看>>
Docker容器内部署Java微服务的内存限制问题
查看>>
pyhanlp用户自定义词典添加实例说明
查看>>
Android开发十年,到中年危机就只剩下这套移动架构体系了!
查看>>
毫米科技:智能家居系统的AI构建思路
查看>>
jdbc8.0 连接 mysql8.0 出现 Public Key Retrieval is not allowed
查看>>
阿里云MVP第八期全球发布,一起出发走向未来
查看>>
我们的手机用上北斗导航了吗?
查看>>
改变ListBoxItem选中的颜色
查看>>
老罗自掏腰包为开源社区捐款,并表示锤子将自己编写OS
查看>>
mysql主从复制(半同步方式)
查看>>
6年来,Docker的这些变化你都知道吗?
查看>>
支付宝客户端架构解析:iOS 客户端启动性能优化初探
查看>>
Maven之pom.xml配置文件详解(转载)
查看>>
优化Git本地仓库
查看>>
对.NET Core未来发展趋势的浅层判断
查看>>
Python高级知识点学习(七)
查看>>
《人月神话》(P7)编写手册和组织开会
查看>>