40. 组合总和 II
# 40. 组合总和 II (opens new window)
# 1.回溯+减枝
难点在于剪枝,考虑如下用例如何进行优化:candidates=[1,1,1,1,3],target=4

剪枝算法有两个关键点:
- 每一层不需要选择重复数字
- 要保证数组中重复数字能够被多次选中
也就说重复数字可以跨层重复选,不能同层重复选。实现时如果当前这层直接过滤重复答案,但是这样一来重复数字在第二层第三层也选不了(违背上面第二条)。因此在剪枝判断加了一层 i>index 判断条件,也就说当前这层无论如何先把第一个index的值选了,再进行同层之间的去重。
class Solution {
List<List<Integer>> res=new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
dfs(new ArrayList<Integer>(),candidates,target,0,0);
return res;
}
public void dfs(List<Integer> path,int[] candidates,int target,int sum,int index){
if(target==sum){
res.add(new ArrayList<>(path));
return ;
}
for(int i=index;i<candidates.length;i++){
if(sum+candidates[i]>target) return;
//剪枝
if(i>index&&candidates[i]==candidates[i-1]){
while(i<candidates.length&&candidates[i-1]==candidates[i])i++;
if(i==candidates.length)return ;
}
path.add(candidates[i]);
dfs(path,candidates,target,sum+candidates[i],i+1);
path.remove(path.size()-1);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
编辑 (opens new window)
上次更新: 2023/12/15, 15:49:57