LeetCode算法题 - 46. 全排列(回溯算法实现)

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;

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值