解法一:用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;
}
};

最新文章

  1. nodejs复习04
  2. row_number和partition by分组取top数据
  3. MyEclipse 中各种 libraries 的含义
  4. 提取安卓手机的recovery
  5. hduoj-----(1068)Girls and Boys(二分匹配)
  6. Eclipse设置模板代码
  7. 另类方法解决设计Web页面出现:Error Creating Control
  8. weblogic数据源配置的问题,weblogic密码破解
  9. jQuery+CSS实现的图片滚动效果
  10. Solr6.0与Jetty、Tomcat在Win环境下搭建/部署
  11. MogoDB(6)--mongoDB高可用和4.0特性
  12. hdu5007 Post Robot AC自动机
  13. Ionic Android项目Splash设置
  14. SQL 从一个表读取数据存到另一个表
  15. 避免crontab输出日志
  16. 在新安装的Linux系统中,防火墙默认是被禁掉的,一般也没有配置过任何防火墙的策略,所有不存在/etc/sysconfig/iptables文件。
  17. 基础概念 之 Spark on Yarn
  18. 《Java程序设计》第7周学习总结 20165218 2017-2018-1
  19. Python Twisted系列教程20: Twisted和Erlang
  20. linux驱动分层分离思想

热门文章

  1. Java实现 LeetCode 813 最大平均值和的分组 (DFS+DP记忆化搜索)
  2. Java实现 蓝桥杯 算法提高 GPA(暴力)
  3. Java实现 LeetCode 479 最大回文数乘积
  4. Java实现 蓝桥杯VIP 算法训练 筛选号码
  5. Java实现 蓝桥杯 素因子去重
  6. Spring 源码学习 - 单例bean的实例化过程
  7. tensorflow2.0学习笔记第二章第三节
  8. springMVC 异常
  9. Kubernetes内部域名解析的那些事儿
  10. [源码解析] Flink的groupBy和reduce究竟做了什么