leetcode46:全排列
数组元素的随机组合,全排列,数列里的 C33 全排列实现
给出一个数字数组<Number>[], 如[1, 2, 3], 如何打印出所有的排列A33(这里打不出来上下标,见谅)。
即: 打印出[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]。
问题分析
- 2个数的全排列
- 3个数转化为2个数
- 4个数转化为3个数
- 方法的专业名词是:邻位互换法
- 如果已经确定好了大小顺序:实现就是字典序法
例如:给定{1,2,3},全排列为3!个,即:
{1,2,3},{1,3,2}
{2,1,3},{2,3,1}
{3,1,2},{3,2,1}
// 2个数的情况(1,2)
[1,2]
[2,1]
// 3个数的情况,与2个数的转化关系
1, [2,3]
2, [1,3]
3, [1,2]
2个数的情况
function sf2() {
var [n1, n2] = [].slice.call(arguments);
return [
[n1, n2],
[n2, n1],
];
}
3个数的情况
function sf3() {
var args = [].slice.call(arguments);
var res = [];
for (var i = 0; i < args.length; i++) {
var value = args[i];
var extra = args.slice(0);
extra.splice(i, 1);
var ret = sf2.apply(null, extra);
ret.forEach((item) => {
item.unshift(value);
});
res = res.concat(ret);
}
return res;
}
4个数的情况
function sf4() {
var args = [].slice.call(arguments);
var res = [];
for (var i = 0; i < args.length; i++) {
var value = args[i];
var extra = args.slice(0);
extra.splice(i, 1);
var ret = sf3.apply(null, extra);
ret.forEach((item) => {
item.unshift(value);
});
res = res.concat(ret);
}
return res;
}
总结
- 2个数的情况
- 其它情况,代码其实是一模一样(参见:
sf4/sf3
代码)
function sf2() {
var [n1, n2] = [].slice.call(arguments);
return [
[n1, n2],
[n2, n1],
];
}
function sf() {
var args = [].slice.call(arguments);
var res = [];
if (args.length === 2) return sf2(...args);
for (var i = 0; i < args.length; i++) {
var value = args[i];
var extra = args.slice(0);
extra.splice(i, 1);
var ret = sf.apply(null, extra);
ret.forEach((item) => {
item.unshift(value);
});
res = res.concat(ret);
}
return res;
}
console.log(sf(1, 2, 3, 4));
知识点
全排列:从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
公式:全排列数f(n)=n!(定义0!=1)
最终实现代码
/**
* @param {number[]} nums
* @return {number[][]}
*/
function sf2() {
var [n1, n2] = [].slice.call(arguments);
return [
[n1, n2],
[n2, n1],
];
}
function permute(nums) {
var args = nums;
var res = [];
if (args.length === 1) return [ args ];
if (args.length === 2) return sf2(...args);
for (var i = 0; i < args.length; i++) {
var value = args[i];
var extra = args.slice(0);
extra.splice(i, 1);
var ret = permute(extra);
ret.forEach((item) => {
item.unshift(value);
});
res = res.concat(ret);
}
return res;
}