原题

给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。

按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

1. "123"
2. "132"
3. "213"
4. "231"
5. "312"
6. "321"

给定 n 和 k,返回第 k 个排列。

说明:

  • 给定 n 的范围是 [1, 9]。
  • 给定 k 的范围是[1, n!]。

示例 1:

输入: n = 3, k = 3
输出: "213"

示例 2:

输入: n = 4, k = 9
输出: "2314"

解法

按照题目所描述的,其实就是按照排列规律,找出相应的数字。

每一位上可以存在的可能数字范围逐渐减少,因此我们需要记录一下当前用过哪些数字

每一位上前缀数字最终对应的可能性也是一个全排列,比如 n 为4时,当第1位定下来一个数字,其对应的所有数字组合有 3!,当第2位定下来后,其对应的数字组合就是2!。当你确认的数字越多,其组合也越少。

直接上代码:

class Solution {
// 当前数字是否用过,默认为false,代表没有用过
boolean[] used; public String getPermutation(int n, int k) {
used = new boolean[n]; int all = 1;
for (int i = n - 1; i > 1; i--) {
all *= i;
} StringBuilder sb = dfs(n, all, k);
return sb.toString();
} /**
* n:当前还剩几个数字没有添加
* all:为了计算出当前数字属于第几组,例如n等于5时,all是4!,这样k/n就知道是第几组了
* k:所求结果是当前组的第几个
*/
public StringBuilder dfs(int n, int all, int k) {
// 组内偏移量
int offset = k % all;
// 当前是第几组
int groupIndex = k / all + (offset == 0 ? 0 : 1); // 在当前没有被访问过的数字里,找第groupIndex个数字
int i = 0;
for (; i < used.length && groupIndex > 0; i++) {
if (!used[i]) {
groupIndex--;
}
}
// 用当前数字
StringBuilder result = new StringBuilder().append(i);
// 标记当前数字已经用过
used[i - 1] = true; // 说明是最后一个数字
if (n == 1) {
return result;
} // 确认一位数字后,其对应的可能性就在减少
return result.append(dfs(n - 1, all / (n - 1), (offset == 0 ? all : offset)));
}
}

提交OK,执行用时:2ms,内存消耗:34.4MB

总结

以上就是这道题目我的解答过程了,不知道大家是否理解了。这道题应该主要就是找规律了,确认好边界情况就应该没什么问题。

有兴趣的话可以访问我的博客或者关注我的公众号、头条号,说不定会有意外的惊喜。

https://death00.github.io/

公众号:健程之道

力扣60——第k个排列的更多相关文章

  1. Java实现 LeetCode 60 第k个排列

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

  2. LeetCode 60 第K个排列

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

  3. LeetCode 60. 第k个排列(Permutation Sequence)

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

  4. 60第K个排列

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

  5. 算法:60.第k个排列

    解答参考:https://blog.csdn.net/lqcsp/article/details/23322951 题目链接:https://leetcode-cn.com/problems/perm ...

  6. 力扣347——前 K 个高频元素

    这道题主要涉及的是对数据结构里哈希表.小顶堆的理解,优化时可以参考一些排序方法. 原题 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2, ...

  7. 力扣 - 347. 前 K 个高频元素

    目录 题目 思路1(哈希表与排序) 代码 复杂度分析 思路2(建堆) 代码 复杂度分析 题目 347. 前 K 个高频元素 思路1(哈希表与排序) 先用哈希表记录所有的值出现的次数 然后将按照出现的次 ...

  8. 代码题(45)— 下一个排列、第k个排列

    1.31. 下一个排列 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只 ...

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

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

随机推荐

  1. [Git] 021 来一颗“恶魔果实”?

    0. 前言 需要新的功能时,一般会新建一条 "feature" 分支(尴尬的是,我第一眼看时,看成了 "future") 在 "feature&quo ...

  2. Spark-Core RDD中函数(变量)传递

    我们进行 Spark 进行编程的时候,初始化工作是在driver端完成的,而实际的运行程序是在executor端进行,所以就涉及到了进程间的通讯,数据是需要序列化的 1.传递函数 import org ...

  3. 关系型数据库为什么喜欢使用B+树作为索引结构? (转)

    问题1. 数据库为什么要设计索引? 图书馆存了1000W本图书,要从中找到<架构师之路>,一本本查,要查到什么时候去? 于是,图书管理员设计了一套规则: (1)一楼放历史类,二楼放文学类, ...

  4. Node.js连接RabbitMQ,断线重连,动态绑定routing key

    RabbitMQ官方提供的教程https://www.rabbitmq.com/tuto...,是基于回调的. 下面将给出基于Promise式的写法.并且实现动态的队列绑定 初始化配置 const a ...

  5. GitHub入门使用

    1.首先注册账号. 2.新建仓库. 3.安装GitBash 4.首先要在本地创建一个ssh key. $ ssh -keygen -t rsa -C "your email@.com&quo ...

  6. oracle数据的导入导出(两种方法三种方式)

    大概了解数据库中数据的导入导出.在oracle中,导入导出数据的方法有两种,一种是使用cmd命令行的形式导入导出数据,另一种是使用PL/SQL工具导入导出数据. 1,使用cmd命令行导入导出数据 1. ...

  7. 线性渐变css

    从上到下的线性渐变: #grad { background: -webkit-linear-gradient(red, blue); /* Safari 5.1 - 6.0 */ background ...

  8. js验证小数或者整数

    利用正则表达式校验是否为小数或者整数,废话不多说直接上demo(此正则表达式无法校验负数和数字为00开头的数字). PS:(如果有不对之处,请批评指教) <!DOCTYPE html> & ...

  9. js随机验证码

    随机验证码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <ti ...

  10. Mysql where in (几百或几千个id)的优化

    1. SELECT employees.* FROM employees, clients WHERE employees.client_id = clients.id AND clients.nam ...