题目

方法
- 关键在于去重复
- 125 215 只能留一个
- 分支间不能重复,分之内可以选择重复数字

class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
boolean[] visited;
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
visited = new boolean[candidates.length];
dfs(candidates, 0, 0, target);
return res;
}
public void dfs(int[] candidates, int start, int sum, int target) {
if (sum == target) {
res.add(new ArrayList<>(path));
return;
}
for (int i = start; i < candidates.length; i++) {
if (i - 1 >= 0 && candidates[i] == candidates[i - 1] && !visited[i - 1]) {
continue;
}
if (sum + candidates[i] > target) {
continue;
}
path.add(candidates[i]);
visited[i] = true;
dfs(candidates, i + 1, sum + candidates[i], target);
path.remove(path.size() - 1);
visited[i] = false;
}
}
}
错误解法:

class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
boolean[] visited;
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
visited = new boolean[candidates.length];
dfs(candidates, 0, 0, target);
return res;
}
public void dfs(int[] candidates, int start, int sum, int target) {
if (sum == target) {
res.add(new ArrayList<>(path));
return;
}
for (int i = start; i < candidates.length; i++) {
if (i - 1 >= 0 && candidates[i] == candidates[i - 1] && visited[i - 1]) {
continue;
}
if (sum + candidates[i] > target) {
continue;
}
path.add(candidates[i]);
dfs(candidates, i + 1, sum + candidates[i], target);
path.remove(path.size() - 1);
visited[i] = true;
}
}
}