46. 全排列
题目连接:https://leetcode-cn.com/problems/permutations/
难度:中等
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:
输入:nums = [0,1]
输出:[[0,1],[1,0]]
示例 3:
输入:nums = [1]
输出:[[1]]
提示:
1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums 中的所有整数 互不相同
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
回溯算法+javascript实现
以示例 1:[1,2,3]
为例,用树状图列出每一个结果
因为排序时有序的,[1,2]
和[2,1]
是不同的排序,所以在第一条树支当第一次取1
后下面,遍历数组的时候,就不能再遍历1
。
所以我在这里使用了一个长度和Nums数组
一样的used数组
来记录已经使用的元素,当Nums数组
中的元素未使用的时候用0
表示,使用过后用1
表示
递归出口
从图可以看到递归的出口,当Path数组
的长度和Nums数组
长度一样的时候,找到了一个全排序,或者Used数组
中的元素全部标记为1
的时候,也是找到了一个全排序。
所以递归出口代码可以这样写,这里用一个Result数组
来保存结果
if (Path.length === Nums.length) {
Result.push(Array.from(Path));//将每一个结果放到Result数组里面
return;
}
Used标记数组
var Used = [];
for (let i = 0; i < Nums.length; i++) {
Used.push(0);
}
深度搜索代码
for (let i = 0; i < Nums.length; i++)//横向遍历每一个数组元素
{
if (Used[i] == 1) {
continue;//如果数组里面为1表示当前的数已经被使用,跳过当前的数
}
else {
Used[i] = 1;//标记当前的数字已经使用
Path.push(Nums[i]);//把当前的数放入Path数组中
backtracking(Nums, Used);//用递归深度搜索树
//回溯
Path.pop();//把当前的数弹出来
Used[i] = 0;//把数标记未使用
}
}
完整代码
function backtracking(Nums, Used) {
if (Path.length === Nums.length) {
Result.push(Array.from(Path));//将每一个结果放到Result数组里面
return;
}
for (let i = 0; i < Nums.length; i++)//横向遍历每一个数组元素
{
if (Used[i] == 1) {
continue;//如果数组里面为1表示当前的数已经被使用,跳过当前的数
}
else {
Used[i] = 1;//标记当前的数字已经使用
Path.push(Nums[i]);//把当前的数放入Path数组中
backtracking(Nums, Used);//用递归深度搜索树
//回溯
Path.pop();//把当前的数弹出来
Used[i] = 0;//把数标记未使用
}
}
};
var Result = [];
var Path = [];
var Used = [];
for (let i = 0; i < Nums.length; i++) {
Used.push(0);
}
backtracking(Nums, Used);
return Result;