真心求大家关注和点赞,原创不易,你们的支持是我写作的最大动力!
题目描述
给你一个数组 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 春招闯关活动」, 点击查看 活动详情