解法一:用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种排列。

  1. 因此如果第 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。

  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。

  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.

  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个排列的更多相关文章

  1. [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 ...

  2. LEETCODE60——第K个排列

    class Solution { public: string getPermutation(int n, int k) { '); vector<bool> flag(n, false) ...

  3. Leetcode60. Permutation Sequence第k个排列

    给出集合 [1,2,3,-,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" "132&qu ...

  4. LeetCode 笔记21 生成第k个排列

    题目是这样的: The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all ...

  5. LinkCode 第k个排列

    http://www.lintcode.com/zh-cn/problem/permutation-sequence/# 原题 给定 n 和 k,求123..n组成的排列中的第 k 个排列. 注意事项 ...

  6. 力扣算法题—060第K个排列

    给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" "132&qu ...

  7. LeetCode 60 第K个排列

    题目: 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" "13 ...

  8. LeetCode(60): 第k个排列

    Medium! 题目描述: 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" ...

  9. LeetCode 中级 - 第k个排列(60)

    可以用数学的方法来解, 因为数字都是从1开始的连续自然数, 排列出现的次序可以推 算出来, 对于n=4, k=15 找到k=15排列的过程: 1 + 对2,3,4的全排列 (3!个) 2 + 对1,3 ...

随机推荐

  1. Java实现 LeetCode 808 分汤 (暴力模拟)

    808. 分汤 有 A 和 B 两种类型的汤.一开始每种类型的汤有 N 毫升.有四种分配操作: 提供 100ml 的汤A 和 0ml 的汤B. 提供 75ml 的汤A 和 25ml 的汤B. 提供 5 ...

  2. Java实现 蓝桥杯 算法提高 分解质因数(暴力)

    试题 算法提高 分解质因数 问题描述 给定一个正整数n,尝试对其分解质因数 输入格式 仅一行,一个正整数,表示待分解的质因数 输出格式 仅一行,从小到大依次输出其质因数,相邻的数用空格隔开 样例输入 ...

  3. Java实现 蓝桥杯 算法提高 套正方形(暴力)

    试题 算法提高 套正方形 问题描述 给定正方形边长width,如图按规律输出层层嵌套的正方形图形. 注意,为让选手方便观看,下图和样例输出均使用""代替空格,请选手输出的时候使用空 ...

  4. Java实现 蓝桥杯VIP 算法训练 入学考试

    问题描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:" ...

  5. Java实现 LeetCode 241 为运算表达式设计优先级

    241. 为运算表达式设计优先级 给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果.你需要给出所有可能的组合的结果.有效的运算符号包含 +, - 以及 * . 示例 ...

  6. 简谈Java语言的继承

    Java语言的继承 这里简谈Java语言的三大特性之二——继承. Java语言的三大特性是循序渐进的.是有顺序性的,应该按照封装-->继承-->多态这样的顺序依次学习 继承的定义 百度百科 ...

  7. 聊聊依赖注入注解@Resource和@Autowired

    1. 前言 @Resource和@Autowired注解都可以在Spring Framework应用中进行声明式的依赖注入.而且面试中经常涉及到这两个注解的知识点.今天我们来总结一下它们. 2. @R ...

  8. YAML语法:

    1.基本语法 k:(空格)v:表示一对键值对(空格必须有): 以空格的缩进来控制层级关系:只要是左对齐的一列数据,都是同一个层级的 server: port: 8081 path: /hello 属性 ...

  9. [ARC060D] 最良表現

    题目   点这里看题目. 分析   由于 KMP 的失配数组有着天然的找循环节的功能,因此我们不难想到对原串进行两次 KMP ,一正一反.   可以发现如下的规律:   1. 原串无循环节,这个时候 ...

  10. windows下Python版本切换使用方法

    由于历史原因,Python有两个大的版本分支,Python2和Python3,又由于一些库只支持某个版本分支,所以需要在电脑上同时安装Python2和Python3,因此如何让两个版本的Python兼 ...