题目介绍
力扣40题:leetcode-cn.com/problems/co…
回溯
该题目是[39. 组合总和]的变形,此时数组candidates中包含有相同的元素,这也需要考虑去重,这里的去重跟[47. 全排列 II]一样,首先将数组candidates进行排序,然后利用一个数组来标识当前节点的访问情况,如果当前元素跟上一个元素相同的,并且上一个元素还没有被访问过,则跳过当前节点。
//用于去重
if(i > 0 && candidates[i-1] == candidates[i] && !visited[i - 1]) {
continue;
}
完整代码如下:
class Solution {
private List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<Integer> path = new ArrayList<>();
//用于去重
boolean[] visited = new boolean[candidates.length];
//排序,方便后面去重
Arrays.sort(candidates);
backTrack(candidates, target, 0, path, 0, visited);
return res;
}
public void backTrack(int[] candidates, int target, int start, List<Integer> path, int curCount, boolean[] visited) {
//满足条件
if(curCount == target) {
res.add(new ArrayList<Integer>(path));
}
// 注意 i 从 start 开始递增
for (int i = start; i < candidates.length; i++) {
if(curCount + candidates[i] > target) {
continue;
}
//用于去重
if(i > 0 && candidates[i-1] == candidates[i] && !visited[i - 1]) {
continue;
}
// 做选择
path.add(candidates[i]);
curCount += candidates[i];
visited[i] = true;
//递归
backTrack(candidates, target, i + 1, path, curCount, visited);
// 撤销选择
path.remove(path.size() - 1);
curCount -= candidates[i];
visited[i] = false;
}
}
}