目录
如果各位对回溯不太了解可以看我昨天写的文章,以及上一篇着重整列了回溯经典的组合问题。
经典的回溯算法题leetcode组合问题整理及思路代码详解-CSDN博客
子集问题
组合问题我们保存的是叶子节点,而子集问题则是非叶子节点也要保存。如果不太了解组合问题的话可能很难理解子集问题,因为子集问题可以说是组合问题的延申。
leetcode78题.子集
给你一个整数数组
nums
,数组中的元素互不相同。返回该数组所有可能的子集(幂集)。解集不能包含重复的子集。你可以按任意顺序返回解集。
示例 1:
输入:nums = [1,2,3] 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0] 输出:[[],[0]]
class Solution {
//保存结果集
List<List<Integer>> res = new ArrayList<>();
//定义临时结点保存子集
List<Integer> temp = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backTrace(nums, 0);
return res;
}
//回溯函数
void backTrace(int[] nums, int index){
// 组合问题会判断搜集到k个数才放进去
//而子集问题叶子节点和非叶子节点都放进去
res.add(new ArrayList<>(temp));
for(int i = index; i < nums.length; i++){
// 从多个元素中选一个
temp.add(nums[i]);
// 递归
backTrace(nums, i + 1);
temp.remove(temp.size() - 1);
}
}
}
leetcode90题.子集II
给你一个整数数组
nums
,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。解集不能包含重复的子集。返回的解集中,子集可以按任意顺序排列。
示例 1:
输入:nums = [1,2,2] 输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
示例 2:
输入:nums = [0] 输出:[[],[0]]
class Solution {
//创建存储结果集
List<List<Integer>> res = new ArrayList<>();
List<Integer> temp = new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
//对数组进行排序,例如就会变成{1,1,2,3}
Arrays.sort(nums);
backTrace(nums, 0);
return res;
}
void backTrace(int[] nums, int index){
res.add(new ArrayList<>(temp));
for(int i = index; i < nums.length; i++){
// 去掉重复子集
if(i > index && nums[i] == nums[i-1]){
continue;
}
// 从多个元素中选一个
temp.add(nums[i]);
// 递归
backTrace(nums, i + 1);
temp.remove(temp.size() - 1);
}
}
}