[LeetCode:permutations] | 刷题打卡

287 阅读2分钟

真心求大家关注和点赞,原创不易,你们的支持是我写作的最大动力!

题目描述

给你一个数组 nums,nums 中数字各不相同,返回 nums 的全排列,顺序不限

例一:

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

例二:

输入: nums = [0,1]
输出: [[0,1],[1,0]]

例三:

输入: nums = [1]
输出: [[1]]

思路分析

这也是一道考察回溯算法的题目,参考之前的解题思路,分析如下:

回溯函数的参数一般为:待选数组集合和已选择的值。这道题只需要待选数组和已选的值就可以了

初始化时:

  • 待选数组就是 nums
  • 已选择的很明显是空

回溯算法体:遍历待选数组,挑一个值放在当前选择的数组中,新的待选数组为去掉当前值的数组,新的待选数组和新的已选择的值进入下一次递归

递归出口:当待选数组长度为 1 时,即只剩下一个元素,把这个值加入到已选择的数组中,将结果 push 到结果数组中返回即可。

AC 代码

这道题是我写的第一个正经的回溯算法的题目,由于对回溯不熟悉,摸不着套路和头脑,很多代码都是不断尝试和摸索写出来的,代码写的有点丑还请见谅,最近为了赶 10 道闯关活动文章,没来得及对它进行重构。

var permute = function (nums1) {
  const result = [];
  const recursion = (nums, acc) => {
    if (nums.length === 1) {
      result.push(nums.concat(acc));
    } else {
      for (let i = 0; i < nums.length; i++) {
        let current = [];
        if (nums.length !== nums1.length) {
          current = [...acc];
        }
        current.push(nums[i]);
        let rest = [];
        // 产生 rest 去递归
        if (i === 0) {
          rest = nums.slice(1);
        } else if (i === nums.length - 1) {
          rest = nums.slice(0, nums.length - 1);
        } else {
          rest = [...nums.slice(0, i), ...nums.slice(i + 1)];
        }
        recursion(rest, current);
      }
    }
  };
  recursion(nums1, []);
};

总结

对于递归的理解,建议大家先做做二叉树的题目,刷几道题以后你就会对递归有新的认识,并且能在实践中更熟练的使用,知道程序会怎么进行递归,怎么进行函数返回。递归是程序设计的基础,很多算法都离不开递归,比如回溯、比如动态规划的思想、比如分治,在熟练掌握递归的基础上再去学这些算法将会事半功倍!

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