题目
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例: 输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3],
[2,3], [1,2], [] ]
思路
子集问题不同于组合问题和分割问题,如果三者都抽象成一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是搜集树的所有节点
回溯三部曲:
- 递归函数参数:全局变量数组path存放子集,二维数组result存放子集组合,并且需要startIndex,因为不能重复取相同的元素
- 递归终止条件:当startIndex 大于数组长度就没有元素可取了
- 单层搜索逻辑:求子集问题不需要剪枝,因为子集就是遍历整棵树
java代码如下:
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums){
subsetsHelper(nums,0);
return result;
}
public void subsetsHelper(int[] nums, int startIndex){
result.add(new ArrayList<>(path));//遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合
if(startIndex >= nums.length){
return;
}//这个代码可以加也可以不加,因为子集需要遍历所有节点,所以可以不用加终止条件
for(int i = startIndex; i < nums.length; i++){
path.add(nums[i]);
subsetsHelper(nums,i+1);
path.remove(path.size()-1);
}
}
}
最后总结:
子集是收集树形结构中树的所有节点的结果
而组合问题、分割问题是收集树形结构中叶子节点的结果