给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路:
全排列是经典回溯算法的应用场景,关于回溯算法的详细介绍,请自行搜索。这里只做简单介绍。
回溯算法是一种类似枚举的搜索尝试过程,主要在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就”回溯“返回,尝试别的路径。
回到这道题,利用回溯算法的思想就是,先把第一个元素 1 拿出来,将其他的元素求全排列;然后把第二个元素 2 拿出来,其他的元素求全排列;第三个元素亦然。
看得出来,也是要用递归的方法。
/**
* @param {number[]} nums
* @return {number[][]}
*/
var permute = function(nums) {
let matrix = [];
const subfunc = (arr, temp) => {
if (arr.length === 0) {
matrix.push(temp)
}
for (let i = 0, len = arr.length; i < len; i++) {
let newarr = arr.slice(0, i).concat(arr.slice(i + 1))
subfunc(newarr, temp.concat(arr[i]))
}
}
subfunc(nums, [])
return matrix;
};
更新
还有一种写法, 也不是完全的新方法. 采用布尔值数组来表示每个数是否访问过.
visited 表示数组的每个值是否被访问过.
var permute = function(nums) {
var res = [];
var visited = Array(nums.length).fill(false);
var temp = [];
const dfs = function(depth) {
if (depth === nums.length) {
res.push(temp.slice());
return;
}
for (let i = 0; i < nums.length; i++) {
if (!visited[i]) {
temp.push(nums[i]);
visited[i] = true;
dfs(depth + 1);
temp.pop(); // 回溯
visited[i] = false;
}
}
}
dfs(0);
return res;
};