LeetCode60. 第k个排列
解法一:用next_permutation()函数,要求第k个排列,就从"123...n"开始调用 k - 1 次 next_permutation()函数即可。
class Solution {
public:
string getPermutation(int n, int k) {
string res;
for(int i = 1; i <= n; ++i) {
res += to_string(i);
}
for(int i = 0; i < k - 1; ++i) {
next_permutation(res.begin(), res.end());
}
return res;
}
};
解法二:
计数,计算第k个排列各个位的数字。
比如 n = 4, k = 10。 假设我们确定了第0位(最高位)的数字,那么剩下三位有三种排列,即剩下(n - 1)! = 3! = 6种排列。
因此如果第 0 位填1,那么当前的排列范围为第1个排列到第6个排列,6 < 10,因此第一个数字不填1。
那么再假设第 0 位填2,这里显然跨过了第 0 位填 1 的6个排列,因此 k - (n - 1)! = 10 - 3 ! = 4,
又由于第 0 位填2的排列也有 3! = 6个,6 > 4,
因此我们可以确定第 10 个排列的第 0 位(第一个数字)填2。然后就是要确定第 1 位(第二个数字),依旧是从小到大枚举:
假设第 1 位填 1,那么剩下没填的位数有两位,剩下的排列数就是 2! = 2, 2 < k (k现在是4)
因此第 1 位 不是填1 ,跳过第 1 位填 1 的所有排列, k 再更新一下:k -= 2! , 现在 k 的值是 2。
那再假设第 1 位填 3 (由于2已经用过了,所以跳过 2),第 0 位 填 2、第 1 位填 3 的排列数为 2, 2 >= k,
所以我们可以确定第 1 位 填3。现在枚举第 2 位(第三个数字)的情况,假设第 2 位填1,剩下只剩一位没填,排列数为 1, 1 < k (k的值是2)
所以跳过第 2 位为 1 的排列,更新k : k -= 1! , k现在为1,
由于2,3都已经用过了,所以跳过,假设第 2 位 填 4: 剩下的排列数为1, 1 >= k,
因此我们得到第 2 位数字为 4.这样第 3 位(第四个数字,即最后一个)只能填 我们还没有填的1.
所以我们知道了当 n 为 4 时,第10个排列的数字为 "2341"
根据上面的思路,得到如下代码:
class Solution {
public:
string getPermutation(int n, int k) {
string res;
vector<bool> used(10); //used记录每个数字是否使用过
for(int i = 0; i < n; ++i) { //枚举每个位置填的数字,确定了 0 ~ n - 1位填的每个数字后就返回结果
int fact = 1; //fact是剩下的位数可以组成的排列数,大小为 (n - i - 1)!
for(int j = 1; j <= n - i - 1; ++j) { //前面已经填了 i + 1位数,剩下的位存在的总排列数就是 (n - (i + 1))!
fact *= j;
}
for(int j = 1; j<= n; ++j) { //从小到大枚举当前位置可以填的数字
if(used[j] == false) { //当前位置只可以填没有用过的数字
if(fact < k) { //如果剩下的排列数小于 k ,说明第k个排列的第 i 个位置的数字不是 j(比 j 大)
k -= fact; //跳过第 i 位为 j 的所有排列,并更新 k
} else {
res += to_string(j); //否则,说明第 k 个排列的第 i 个数字为 j
used[j] = true; //记录数字 j 已经被使用过,后面的位置就不能再填 j 了
break; //已经确定了第 i 位的数字,跳出当前循环,继续判断 i + 1(下一位)的数字
}
}
}
}
return res;
}
};
LeetCode60. 第k个排列的更多相关文章
- [Swift]LeetCode60. 第k个排列 | Permutation Sequence
The set [1,2,3,...,n] contains a total of n! unique permutations. By listing and labeling all of the ...
- LEETCODE60——第K个排列
class Solution { public: string getPermutation(int n, int k) { '); vector<bool> flag(n, false) ...
- Leetcode60. Permutation Sequence第k个排列
给出集合 [1,2,3,-,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" "132&qu ...
- LeetCode 笔记21 生成第k个排列
题目是这样的: The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all ...
- LinkCode 第k个排列
http://www.lintcode.com/zh-cn/problem/permutation-sequence/# 原题 给定 n 和 k,求123..n组成的排列中的第 k 个排列. 注意事项 ...
- 力扣算法题—060第K个排列
给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" "132&qu ...
- LeetCode 60 第K个排列
题目: 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" "13 ...
- LeetCode(60): 第k个排列
Medium! 题目描述: 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" ...
- LeetCode 中级 - 第k个排列(60)
可以用数学的方法来解, 因为数字都是从1开始的连续自然数, 排列出现的次序可以推 算出来, 对于n=4, k=15 找到k=15排列的过程: 1 + 对2,3,4的全排列 (3!个) 2 + 对1,3 ...
随机推荐
- Java实现 LeetCode 808 分汤 (暴力模拟)
808. 分汤 有 A 和 B 两种类型的汤.一开始每种类型的汤有 N 毫升.有四种分配操作: 提供 100ml 的汤A 和 0ml 的汤B. 提供 75ml 的汤A 和 25ml 的汤B. 提供 5 ...
- Java实现 蓝桥杯 算法提高 分解质因数(暴力)
试题 算法提高 分解质因数 问题描述 给定一个正整数n,尝试对其分解质因数 输入格式 仅一行,一个正整数,表示待分解的质因数 输出格式 仅一行,从小到大依次输出其质因数,相邻的数用空格隔开 样例输入 ...
- Java实现 蓝桥杯 算法提高 套正方形(暴力)
试题 算法提高 套正方形 问题描述 给定正方形边长width,如图按规律输出层层嵌套的正方形图形. 注意,为让选手方便观看,下图和样例输出均使用""代替空格,请选手输出的时候使用空 ...
- Java实现 蓝桥杯VIP 算法训练 入学考试
问题描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:" ...
- Java实现 LeetCode 241 为运算表达式设计优先级
241. 为运算表达式设计优先级 给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果.你需要给出所有可能的组合的结果.有效的运算符号包含 +, - 以及 * . 示例 ...
- 简谈Java语言的继承
Java语言的继承 这里简谈Java语言的三大特性之二——继承. Java语言的三大特性是循序渐进的.是有顺序性的,应该按照封装-->继承-->多态这样的顺序依次学习 继承的定义 百度百科 ...
- 聊聊依赖注入注解@Resource和@Autowired
1. 前言 @Resource和@Autowired注解都可以在Spring Framework应用中进行声明式的依赖注入.而且面试中经常涉及到这两个注解的知识点.今天我们来总结一下它们. 2. @R ...
- YAML语法:
1.基本语法 k:(空格)v:表示一对键值对(空格必须有): 以空格的缩进来控制层级关系:只要是左对齐的一列数据,都是同一个层级的 server: port: 8081 path: /hello 属性 ...
- [ARC060D] 最良表現
题目 点这里看题目. 分析 由于 KMP 的失配数组有着天然的找循环节的功能,因此我们不难想到对原串进行两次 KMP ,一正一反. 可以发现如下的规律: 1. 原串无循环节,这个时候 ...
- windows下Python版本切换使用方法
由于历史原因,Python有两个大的版本分支,Python2和Python3,又由于一些库只支持某个版本分支,所以需要在电脑上同时安装Python2和Python3,因此如何让两个版本的Python兼 ...