LeetCode 👉 HOT 100 👉 全排列 - 中等题

198 阅读2分钟

这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战

题目

给定一个不含重复数字的数组 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]]

思路

题目的标题已经很明显了,告诉解答者,本题求的就是所有的可能组合,全排列。那么对于全排列这种很经典的题目,回溯算法,是比较好的求解途径,具体想法如下:

  • 定一个 Array 类型的变量 ans 用于存放结果

  • 定义一个递归函数 getCombination,接受两个参数 arrhasUse

    • arr 为当前的部分组合,如 [1],是一个未完成,但是可能的结果

    • hasUseObject 结构,用于存放当前 arr 中已使用的元素

    • 每次递归函数进来,先判断 arr.length == nums.length 是否成立,成立 arr 即是一个答案中的元素,如 [1,2,3]

    • 上述步骤不成立,则对题目所给数组进行遍历

      • 如果参数 hasUse 中不存在 nums[i],则将 nums[i] 分别放入 arrhasUse 中形成两个新的参数,继续调用 getCombination 函数
  • 用参数 [], {} 启动递归函数 getCombination

  • 递归结束后,返回 ans 即为题目所求

代码如下

    /**
     * @param {number[]} nums
     * @return {number[][]}
     */
    var permute = function(nums) {
        let ans = [];
        const getCombination = (arr, hasUse) => {
            if(arr.length == nums.length) {
                ans.push(arr);
                return;
            }
            for(let i = 0; i < nums.length; i++) {
                if(!hasUse[nums[i]]) {
                    let newArr = [...arr, nums[i]]
                    getCombination(newArr, {...hasUse, [nums[i]]: 1})
                }
            }
        }
        getCombination([], {});
        return ans;
    };

小结

算法需要多练才会有思路,看到 全排列 就应该想到 回溯,回溯的过程中,不同的情况需要采用不同的剪枝方法

LeetCode 👉 HOT 100 👉 全排列 - 中等题

合集:LeetCode 👉 HOT 100,有空就会更新,大家多多支持,点个赞👍

如果大家有好的解法,或者发现本文理解不对的地方,欢迎留言评论 😄