LeetCode(60): Permutation Sequence (C++)
2015-12-01 10:44
525 查看
一、题目
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):
"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutation sequence.
二、分析
此题可用暴力枚举,即调用 k - 1 次的 std::next_permutation() 或者是在 LeetCode(31): Next Permutation所实现的函数,但这样做求出了前 k 个所有排列,会超时,我们只需要求出第 k 个即可。
为了能更清楚地说明接下来的算法,我们先来看对于 n = 3 时,所有排列的特点。
可分为 n = 3 组,每组有 (n - 1)! 即 (3 - 1)! 个排列;
第 m 组(其中, 1 ≤ m ≤ n)中,第一个数为所有数字升序排列的第 m 个数,如:第 3 组第一个数为 [1, 2, 3] 的第三个数,即3;
第 m 组的第一个排列,即总的第 (m - 1) * (n - 1)! + 1 个排列,第一个数之后,为升序排列;
第 m 组的最后一个排列,即总的第 m * (n - 1)! 个排列,第一个数之后,为降序排列;
有此规律,我们便可递归求解,即总的 n 个数的第 k 个排列,可以通过确定第一个数之后,求剩下的 (n - 1) 个数的第 k - m * (n - 1)! 个排列,其中,m = floor(k / (n - 1)!)。
三、代码实现
class Solution {private:
long fact(int n){
if(n == 0){
return 1;
}else{
return n * fact(n - 1);
}
}
void permute(string& str, int start, int k){
if(k == 1 || k == 0){
return;
}
const int len = str.size();
if(k == fact(len - start)){
sort(str.begin() + start, str.end(), greater<char>());
return;
}else{
int tmp = fact(len - start - 1);
int num = k / tmp;
k -= num * tmp;
if(k == 0){
swap(str[start], str[start + num - 1]);
sort(str.begin() + start + 1, str.end(), greater<char>());
}else{
swap(str[start], str[start + num]);
sort(str.begin() + start + 1, str.end());
}
permute(str, start + 1, k);
}
}
public:
string getPermutation(int n, int k) {
string s;
int sum = 0;
s.resize(n);
for_each(s.begin(), s.end(), [&sum](char& c){ c = '0' + (++sum); });
permute(s, 0, k);
return s;
}
};
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C++联合体转换成C#结构的实现方法
- C#实现的算24点游戏算法实例分析
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析