「LeetCode」46-全排列

202 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

一.题目:

给定一个不含重复数字的数组 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 中的所有整数 互不相同

二、思路分析:

首先这道题目是一个中等的难度,它要求我们能够将给定的数组进行全排列,然后将每个排列组合进行展示,要求不能够漏掉所有结果,对于这种全排列问题,我们一般都是利用回溯法来进行题目的求解的。

回溯法的思路就是:在选择列表里做选择,然后用选择构建路径,如果符合则将选择列表的某值择出,然后继续构建路径直到满足题目的要求为止,这样能够找到一个结果,随后需要撤销选择再将这个选择放入选择列表中,一直循环至所有情况完成即可完成作答。

对于本题目的思路:

  1. 需要构建已经选择的路径以及选择列表
  2. 套用回溯方法的思路框架进行代码的填充
  3. 每次在循环中递归过后都需要取消选择进入下一个不同的路径

三、代码:

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var permute = function(nums) {
    if(nums.length == 1) return [nums]
    let res = []
    //已经选择的路径
    let selectarr = []
    //可选择的数组,先初始化全部可以选择
    let unselectarr = new Array(nums.length).fill(true)
    //回溯算法实现全排列,需要路径和选择列表
    const backtrack = function(nums,selectarr,unselectarr){
        //结束条件
        
        if(selectarr.length == nums.length){
            let temp = JSON.parse(JSON.stringify(selectarr))
            res.push(temp)
            return
        }
        for(let i = 0 ; i < nums.length ; i++){
            if(!unselectarr[i]){
                continue
            }
            selectarr.push(nums[i])
            unselectarr[i] = false
            backtrack(nums,selectarr,unselectarr)
            //取消选择
            selectarr.pop()
            unselectarr[i] = true
        }
    }
    backtrack(nums,selectarr,unselectarr)
    return res
};

四、总结:

对于这道题目我们需要注意,在找到一个路径的时候,我们如果是直接将结果push进入结果数组,那么答案一定是错误的,因为我们的结果是一个数组,如果我们后续还会更改里面的内容的时候,结果数组里面的值会跟着变化,所以我们添加的时候需要进行深拷贝。