[leetcode] 40. 组合总和 II
这题跟上题做法几乎一样,只不过每个数能取多次改成了最多能取一次,同时candidates可能会出现相同字符,感觉还没有上一个题难。
代码仅需改两处即可,直接看代码把,有注释的地方即是改过的
class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> ans = new ArrayList<>();
if (candidates.length == 0) return new ArrayList<>();
Arrays.sort(candidates);
for (int k = 1; k <= candidates.length; k++) {
dfs(k, 0, candidates, new ArrayList<>(), 0, target, ans);
}
// 由于candidates可能会出现重复,所以我们对结果集做下去重即可
return ans.stream().distinct().collect(Collectors.toList());
}
public void dfs(int k, int i, int[] candidates, List<Integer> now, int nowCnt, int target, List<List<Integer>> ans) {
if (nowCnt > target) {
return;
}
if (k == 0 && nowCnt == target) {
ans.add(new ArrayList<>(now));
return;
}
if (i >= candidates.length) return;
int num = candidates[i];
// 取多次改成了最多能取一次,也就是从0~多改成了0~1。
for (int j = 0; j <= 1; j++) {
if (nowCnt + j * num > target) {
break;
}
for (int q = 1; q <= j; q++) {
now.add(num);
}
dfs(k - j, i + 1, candidates, now, nowCnt + j * num, target, ans);
// 回溯的时候需要注意,现在只需要rm一个就好了
if (j == 1) {
now.remove(Integer.valueOf(num));
}
}
}
}