LeetCode 46. 全排列 --javascript DFS

46. 全排列

描述

给定一个不含重复数字的数组 nums ,返回其 全部可能的全排列 。你能够 按任意顺序 返回答案。javascript

示例 1:java

输入: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]]
复制代码

提示:markdown

1 <= nums.length <= 6
-10 <= nums[i] <= 10
复制代码

题解

回溯法

回溯法(backtracking)是优先搜索的一种特殊状况,又称为试探法,经常使用于须要记录节点状态的深度优先搜索。一般来讲,排列、组合、选择类问题使用回溯法比较方便。 顾名思义,回溯法的核心是回溯。在搜索到某一节点的时候,若是咱们发现目前的节点(及其子节点)并非需求目标时,咱们回退到原来的节点继续搜索,而且把在目前节点修改的状态 还原。spa

这样的好处是咱们能够始终只对图的总状态进行修改,而非每次遍历时新建一个图来储存 状态。 在具体的写法上,它与普通的深度优先搜索同样,都有 [修改当前节点状态]→[递归子节 点] 的步骤,只是多了回溯的步骤,变成了 [修改当前节点状态]→[递归子节点]→[回改当前节点 状态]。 回溯法。有两个小诀窍,一是按引用传状态,二是全部的状态修 改在递归完成后回改。 回溯法修改通常有两种状况,一种是修改最后一位输出,好比排列组合;一种是修改访问标 记,好比矩阵里搜字符串。code

分析

怎样输出全部的排列方式呢?对于每个当前位置 i,咱们能够将其于以后的任意位置交换, 而后继续处理位置 i+1,直处处理到最后一位。为了防止咱们每此遍历时都要新建一个子数组储 存位置 i 以前已经交换好的数字,咱们能够利用回溯法,只对原数组进行修改,在递归完成后再 修改回来。 咱们以样例[1,2,3]为例,按照这种方法,咱们输出的数组顺序为[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]],能够看到全部的排列在这个算法中都被考虑到了。orm

coding

/** * @param {number[]} nums * @return {number[][]} */
var permute = function(nums) {
   let ans = [];
   let start = 0, len = nums.length, _start = 0;
   backtracking(nums, start, ans);
   return ans;
};

const backtracking = function(_nums, level, ans) {
    if(level === _nums.length - 1) {
        ans.push([..._nums]);
        return;
    }
    for(let i = level; i < _nums.length; i++) {
        [_nums[i], _nums[level]] = [_nums[level], _nums[i]] // 修改当前节点状态
        backtracking(_nums, level + 1, ans); // 递归子节点
        [_nums[i], _nums[level]] = [_nums[level], _nums[i]] // 恢复当前节点状态
    }
}

复制代码
相关文章
相关标签/搜索