一天一大 lee(第k个排列)难度:中等-Day20200905
时间:2022-07-25
本文章向大家介绍一天一大 lee(第k个排列)难度:中等-Day20200905,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目:[1]
给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
- "123"
- "132"
- "213"
- "231"
- "312"
- "321" 给定 n 和 k,返回第 k 个排列。
说明:
- 给定 n 的范围是 [1, 9]。
- 给定 k 的范围是[1, n!]。
示例:
- 示例 1
输入: n = 3, k = 3
输出: "213"
- 示例 2
输入: n = 4, k = 9
输出: "2314"
抛砖引玉
抛砖引玉
思路
从1到n转换成从n到1,共有n的阶乘种组合;
分析排列过程:
- 1开始的排列(n-1)的阶乘种组合
- 2开始的排列(n-1)的阶乘种组合 ....
- n开始的排列(n-1)的阶乘种组合
结合排列的顺序和k的大小,此时可以确定第一个字符
第二个字符:
- 此时已知两个字符剩余字符的组合种类数为(n-2)的阶乘,n-1的阶乘除以n-1
第三个字符:
- 此时已知三个字符剩余字符的组合种类数为(n-3)的阶乘,n-2的阶乘除以n-2
...
知道第k中排列或者最终n-x等于1得到最终排列
数学
/**
* @param {number} n
* @param {number} k
* @return {string}
*/
var getPermutation = function (n, k) {
let _result = '',
nums = [], // 存放待排列元素
factorial = 1;
for (let i = 1; i <= n; i++) {
nums.push(i);
factorial = factorial * i;
}
// 计数和索引差1
k= k-1;
while (nums.length > 0) {
factorial = factorial / nums.length; // 确定一个元素后,待排列的组合种类减少为(n-x)的阶乘
let index = parseInt(k / factorial,10); // 当前选择的数字的索引
_result += nums[index]; // 加上当前选的数字
nums.splice(index, 1); // nums删去选的这个数字
k = k % factorial; // 更新 k,
}
return _result;
}
回溯法
上面的数学法并没有生成具体的组合,都是通过确定元素后能得到的排列组合数来推导出第k个排列
更直观的方法是,枚举每个位置上可能的元素然后记录其对应的种类数,直到枚举到第k
递归选择要拼接的元素:
- 参数:已选择的元素数组
- 终止:所有元素均被选择
var getPermutation = function (n, k) {
let used = new Map(),
factorial = 1;
for (let i = 1; i <= n; i++) {
factorial = factorial * i;
}
function helper(temp) {
let len = temp.length;
if (len == n) return temp.join('');
factorial = factorial / (n - len); // 待排列的元素存在的组合数
for (let i = 1; i <= n; i++) {
if (used.has(i)) continue; // 递归时忽略已经排列的元素
if (k > factorial) { // 如果k大于剩余的组合数,则说明如果此位置排列i则排列完成不能有k种组合
k = k - factorial;
continue;
}
temp.push(i); // 满足此位置选择i包含大于等于k中组合
used.set(i, true);
return helper(temp); // 继续选择i后面的元素
}
};
return helper([]);
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- linux常用的读取文件内容指令
- Executors.newSingleThreadScheduledExecutor();线程池中放入多个线程问题
- SqlServer批量删除表
- java 获取一天内crontab任务执行的时间点
- Python自学成才之路 魔术方法之一元,二元运算符
- Python自学成才之路 魔术方法之打印对象实例
- Python自学成才之路 装饰器必用的wraps注解
- Python自学成才之路 使用函数作为装饰器
- Python自学成才之路 装饰器编程之初试装饰器
- Python自学成才之路 元类中的__new__和__init__方法
- Centreon+Nagios实战第七篇——安装NRPE
- Python自学成才之路 详解类的三个重要方法__new__,__init__,__call__
- Centreon+Nagios实战第五篇——监控端安装Centreon
- Centreon+Nagios实战第四篇——监控端安装NDOUtils
- python自学成才之路 类属性和实例属性,__slots__方法