一些子集问题要记录树上的所有节点,因此终止条件可加可不加
1. 子集
该题和排列问题基本相似,本题需要收集所有的结果。
class Solution {
List<List<Integer>> result = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> subsets(int[] nums) {
if(nums.length==0){
result.add(new ArrayList<>(path));
return result;
}
subsetsHelper(nums,0);
return result;
}
void subsetsHelper(int[] nums,int startIndex){
//要添加每一组元素
result.add(new ArrayList<>(path));
for(int i = startIndex;i<nums.length;i++){
path.add(nums[i]);
subsetsHelper(nums,i+1);
path.removeLast();
}
}
}
2.子集 II
去重,建立一个boolean数组。
class Solution {
List<List<Integer>> res = new ArrayList<>();//存放答案
LinkedList<Integer> path = new LinkedList<>();//用来存放符合条件的结果
boolean[] used;//用来去重的数组
public List<List<Integer>> subsetsWithDup(int[] nums) {
if(nums.length==0){
res.add(new ArrayList<>(path));
return res;
}
Arrays.sort(nums);
used = new boolean[nums.length];
subsetsWithDupHelper(nums,0);
return res;
}
//startIndex表示嵌套了几个for循环
void subsetsWithDupHelper(int[] nums,int startIndex){
//终止条件
res.add(new ArrayList<>(path));
for(int i = startIndex;i<nums.length;i++){
//去重,去重同枝,不去重同层
if(i>0&&nums[i]==nums[i-1]&&!used[i-1]){
continue;
}
path.add(nums[i]);
used[i]=true;
subsetsWithDupHelper(nums,i+1);
//回溯
path.removeLast();
used[i]=false;
}
}
}
3.递增子序列
去重
class Solution {
List<List<Integer>> res = new ArrayList<>();//输出答案
LinkedList<Integer> path = new LinkedList<>();//记录路径
public List<List<Integer>> findSubsequences(int[] nums) {
backTracking(nums,0);
return res;
}
void backTracking(int[] nums,int startIndex){
//确定终止条件
if(path.size()>1){
res.add(new ArrayList<>(path));
//return;
}
//单层逻辑
int[] used = new int[201];
for(int i=startIndex;i<nums.length;i++){
//去重
if(!path.isEmpty()&&nums[i]<path.get(path.size()-1)||(used[nums[i]+100]==1)){
continue;
}
used[nums[i]+100]=1;
path.add(nums[i]);
//回溯
backTracking(nums,i+1);
path.removeLast();
}
}
}