LeetCode: 46.全排列 | 刷题打卡

360 阅读2分钟

本文正在参与掘金团队号上线活动,点击 查看大厂春招职位

一、题目描述

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]
输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

二、思路分析

简单来说,就是根据给定的数组,进行所有情况的排列,且不能有重复元素。

首先,进行所有情况的排列,那么很直接就可以想到使用穷举法,即从左到右的每一个位置都依次尝试填入一个数,看能不能得到满足要求的排列。

其次不能有重复的元素,那么这里面有出路也有死路,非常符合使用 回溯算法 的场景。

步骤一: 使用递归模拟出所有排列的情况;

步骤二: 遇到包含重复元素的情况,就进行回溯(终止递归);

步骤三: 收集所有到达递归终点的排列情况,并且进行返回。

三、AC 代码

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var permute = function(nums) {
    const res = []
    
    // 回溯
    const backtrack = (path) => {
        // 终点,当 path 的 length 和 nums 的 length 相等的时候,记录这一次的 path 并结束递归
        if(path.length === nums.length) {
            return res.push(path)
        }
        
        // 通过循环加递归的形式,模拟出所有的排列情况
        nums.forEach(v => {
            // 当 path 中,包含这一次的循环的值的时候,进行回溯(中断递归)
            if(path.includes(v)) return 
            
            // 递归
            backtrack(path.concat(v))
        })
    }
    backtrack([])
    
    return res
};

四、总结

像这种需要去进行穷举法且存在出路和死路的情况,就可以使用回溯算法了

关注点在于如何去模拟出所有情况,以及出路和死路的判断。

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情