一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
一.题目:
78. 子集 给你一个整数数组
nums,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入: nums = [1,2,3]
输出: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入: nums = [0]
输出: [[],[0]]
提示:
1 <= nums.length <= 10-10 <= nums[i] <= 10nums中的所有元素 互不相同
二、思路分析:
这道题目依然可以用回溯的方法进行求解,因为一旦涉及排列选择问题的时候,利用回溯方法进行求解都是可以完整的做出来的。因为这道题目要求我们不能够包含重复的子集,所以对于[1,3]和[3,1],这种子集就是重复的,所以我们需要避免产生重复的子集。
所以我们需要利用回溯的方法不断地去遍历数组中的数字,然后到达数组的末尾的时候撤销我们的选择继续进行递归,每次计入函数时我们需要将子集存入结果集中,注意结果集推入的数组需要进行深拷贝,注意这些小细节我们就能够完成题目的求解。
基本的图解就是下图所示:
三、代码:
var subsets = function (nums) {
//回溯法进行求解
let res = []
let track = []
// res.push([])
const backtrack = function (nums, start) {
res.push(track.slice())
//使用start避免产生重复的子集
for (let i = start; i < nums.length; i++) {
//base case
track.push(nums[i])
backtrack(nums,i+1)
track.pop()
}
}
backtrack(nums, 0)
return res
};
四、总结:
这道题目的回溯方法没有base case是因为我们设置了start保证了它到达数组的结尾的时候会结束循环,而且如果没有特别的条件,base case也可能不需要用到。回溯法真的能够求解大多数问题,所以希望自己能够完全掌握。