LeetCode:60. Permutation Sequence,全排列的第n个子列
2017-05-02 20:04
375 查看
LeetCode:60. Permutation Sequence,n全排列的第k个子列 :
题目:
LeetCode: 60. 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):
“123”
“132”
“213”
“231”
“312”
“321”
Given n and k, return the kth permutation sequence.
Note: Given n will be between 1 and 9 inclusive.
简要概括内容 :寻找到给定n的集合(n = 3 ,[1,2,3]),寻找它的kth个全排列子列。
分析:
方法一: 利用STL中的next_permutation函数实现
特点:代码简洁,暴力枚举
方法二: 利用康托逆展开的方式进行快速寻找,关于康托展开
特点:快速有效
代码:
:
/[b]***********************************2017年5月3日更新*****************************************************[/b]/
测试代码:
备注:
此处对康托逆展开做一个说明:
为了寻找到 n = 5 , k = 6的子序列步骤如下:
1. n = 5,则说明初始序列为“12345”,使用a1、a2、a3、a4、a5表示;
2. 根据康托逆展开中描述,该序列变化了k = k - 1 = 5次,即在 “12345“的第五个序列
3. a1 = k / (n - 1)! = 5 / 4! = 0; // 整除 第一位数字为比“1”大0的数字“1”
4. k1 = k % (n - 1)! = 5 % 4! = 5; // k1 作为下一次运算的k 带入算式
5. a2 = k1 / (n - 2)! = 5 / 3! = 0; //整除 第二位数字为比“2”大0的数字,“1” 已经被“取”走所以此处取“2”
6. k2 = k1 % (n - 2)! = 5 % 3! = 5; // k2 作为下一次运算的k 带入算式
7. a3 = k2 / (n - 3)! = 5 / 2! = 2; //整除 第三位数字为比“3”大2的数字,(“1”“2” 已经被“取”走)此处取“5”
6. k3 = k2 % (n - 3)! = 5 % 2! = 1; // k3 作为下一次运算的k 带入算式
7. a4 = k2 % (n - 4)! = 1 / 1 = 1; // 第四位数字为比“3”大1的数字,(“1”“2” 已经被“取”走)此处取“4”
8. k4 = k3 % (n - 4)! = 5 % 2! = 0; // k3 作为下一次运算的k 带入算式
9. a5 为剩余的 “3”;// 当然程序设计的时候只需要对 (n - i)!进行非0处理就可以了,不需要单独进行循环外处理。
算法逻辑:
1. 通过n,k创建初始化的 strTemp;
2. 开始寻找第K序列;// 第k = k - 1个
寻找a1 ; // a = k / (n - 1)!;
k = k % (n - 1)!;
将a存入 输出数据strRes中;
移除str[a1]元素
重复上述。
谢谢小伙伴提的意见,后续博客会更新leetcode相关内容。本来不打算写下来的,毕竟leetcode题目博客在网上一大抄,但是个人还是觉得吸取大家的意见,顺路巩固加强下自己的理解,好记性不如烂笔头!
题目:
LeetCode: 60. 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):
“123”
“132”
“213”
“231”
“312”
“321”
Given n and k, return the kth permutation sequence.
Note: Given n will be between 1 and 9 inclusive.
简要概括内容 :寻找到给定n的集合(n = 3 ,[1,2,3]),寻找它的kth个全排列子列。
分析:
方法一: 利用STL中的next_permutation函数实现
特点:代码简洁,暴力枚举
方法二: 利用康托逆展开的方式进行快速寻找,关于康托展开
特点:快速有效
代码:
:
string getPermutationEx(int n, int k) { string s(n, '0'); for (int i = 0; i < n; ++i) { s[i] = i + 1; } for (int i = 0; i < k - 1; ++i) { next_permutation(s.begin(), s.end()); } return s; }
string getPermutation(int n, int k) { string strTemp(n, '0'); string strRes; for (int i = 0; i < n; ++i) { strTemp[i] += i + 1; } int nNum = 1; int nTemp = n; while (0 != --nTemp) { nNum *= nTemp; } int kTemp = k - 1; int nA; nTemp = n - 1; for (auto iterBg = strTemp.begin(); iterBg != strTemp.end();) { nA = kTemp / nNum; // a = k / (n - 1)!; kTemp = kTemp % nNum; // k = k % (n - 1)!; strRes.push_back(strTemp[nA]); strTemp.erase(iterBg + nA); nNum = nNum / (nTemp ? nTemp : 1); --nTemp; } return strRes; }
/[b]***********************************2017年5月3日更新*****************************************************[/b]/
测试代码:
// test for Permutation Sequence int main() { string s = getPermutation(1, 1); for (int i = 0; i < s.size(); ++i) { printf("%c", s[i]); } }
备注:
此处对康托逆展开做一个说明:
为了寻找到 n = 5 , k = 6的子序列步骤如下:
1. n = 5,则说明初始序列为“12345”,使用a1、a2、a3、a4、a5表示;
2. 根据康托逆展开中描述,该序列变化了k = k - 1 = 5次,即在 “12345“的第五个序列
3. a1 = k / (n - 1)! = 5 / 4! = 0; // 整除 第一位数字为比“1”大0的数字“1”
4. k1 = k % (n - 1)! = 5 % 4! = 5; // k1 作为下一次运算的k 带入算式
5. a2 = k1 / (n - 2)! = 5 / 3! = 0; //整除 第二位数字为比“2”大0的数字,“1” 已经被“取”走所以此处取“2”
6. k2 = k1 % (n - 2)! = 5 % 3! = 5; // k2 作为下一次运算的k 带入算式
7. a3 = k2 / (n - 3)! = 5 / 2! = 2; //整除 第三位数字为比“3”大2的数字,(“1”“2” 已经被“取”走)此处取“5”
6. k3 = k2 % (n - 3)! = 5 % 2! = 1; // k3 作为下一次运算的k 带入算式
7. a4 = k2 % (n - 4)! = 1 / 1 = 1; // 第四位数字为比“3”大1的数字,(“1”“2” 已经被“取”走)此处取“4”
8. k4 = k3 % (n - 4)! = 5 % 2! = 0; // k3 作为下一次运算的k 带入算式
9. a5 为剩余的 “3”;// 当然程序设计的时候只需要对 (n - i)!进行非0处理就可以了,不需要单独进行循环外处理。
算法逻辑:
1. 通过n,k创建初始化的 strTemp;
2. 开始寻找第K序列;// 第k = k - 1个
寻找a1 ; // a = k / (n - 1)!;
k = k % (n - 1)!;
将a存入 输出数据strRes中;
移除str[a1]元素
重复上述。
谢谢小伙伴提的意见,后续博客会更新leetcode相关内容。本来不打算写下来的,毕竟leetcode题目博客在网上一大抄,但是个人还是觉得吸取大家的意见,顺路巩固加强下自己的理解,好记性不如烂笔头!
相关文章推荐
- LeetCode:60. Permutation Sequence,n全排列的第k个子列
- LeetCode题解-全排列的第k个数字(全排列变体)
- leetcode-46. Permutations(非重复元素全排列)
- leetcode-47. Permutations II(重复元素全排列)
- [LeetCode] 46. Permutations 全排列
- LeetCode(Permutations) 数列的全排列
- LeetCode 46 Permutations(全排列问题)
- Python查找第n个子串的技巧分享
- Leetcode全排列问题
- LeetCode-------60. Permutation Sequence(n的全排列中第K列)
- LeetCode | Permutation Sequence(找到全排列中的第k个排列)
- [LeetCode] 47. Permutations II 全排列 II
- [Leetcode] remove nth node from the end of list 删除链表倒数第n各节点
- LeetCode 47 Permutations II(全排列)
- 一次搞懂全排列——LeetCode四道Permutations问题详解
- 32.1 leetcode - 没有重复数据的全排列
- leetcode177-Nth Highest Salary(找出第n大的数据)
- LeetCode(Permutation Sequence)输出全排列中第k个排列
- [LeetCode] “全排列”问题系列(一) - 用交换元素法生成全排列及其应用,例题: Permutations I 和 II, N-Queens I 和 II,数独问题
- LeetCode 60. Permutation Sequence 全排列的第k个