leetcode46.全排列

49 阅读2分钟

image.png

全排列是一道经典的利用回溯来解题的题目,首先来了解一下什么是回溯算法。

回溯算法

回溯算法是一种递归算法,主要用于解决通过搜索所有可能的解来找到最优解或所有可行解的问题,它是构建解决方案的一部分,并通过探索每个可能的步骤来找到完整的解决方案,如果发现当前步骤不符合条件,则回溯到上一步,尝试其他可能的步骤。

主要用途

回溯算法主要用于解决如下类型的问题

1、组合问题:从一个集合中选择若干元素组成组合,例如组合,子集等问题

2、排列问题:生成集合中元素的全排列

3、子集问题:生成子集的所有子集

4、数独和棋盘问题:如数独求解,N皇后问题

5、图的搜索问题:如图的所有路径、迷宫求解等

回溯算法解题模板

function backtrack() 
{ if 满足结束条件 记录或输出结果 return } 
for in option 
执行操作 
backtrack(更新track,更新option) 
撤销操作

全排列解题思路

给定一个不含重复数字的数组,返回其所有可能的全排列,你可以按任意顺序返回答案

1、写回溯函数

function backtrack(nums, used)

2、满足结束条件:暂存数组的长度等于给定的数组长度

if(temp.length === nums.length)

3、循环遍历操作

for(let i = 0; i < nums.length-1; i++){
if(used[i] continue)
temp.push(nums[i])
used[i] = true
backtrack(nums, used)//一直递归下去,知道不满足条件或者已经输出满足条件的结果
temp[i].pop()//执行回溯,退回到上一阶段
used[i] = false//更改状态
}

完整代码

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var permute = function(nums) {
    //需要三个初始化三个值,一个是存放最终结果的图,一个表示数组中每个值的状态,一个是
    let result = [];
    let used = new Array(nums.length).fill(false) //先把每个数初始化为false
    let temp = []
    function permutations (nums, used){
        if(temp.length == nums.length){
            result.push(Array.from(temp))
            return
        }
        for(let i = 0; i<nums.length; i++){
            if(used[i]) continue;
            temp.push(nums[i]);
            used[i] = true;
            permutations(nums, used)
            temp.pop(); // 撤销选择
            used[i] = false; // 撤销标记
        }
    }
     permutations(nums, used);
    return result;
};