题目链接
思路:
这道题与39题思路一致,只是在添加结果的过程中,要做到不重复,那么需要在回溯的过程中进行剪枝,当出现与之前数相同时,需要跳过这个数不选。
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
if (candidates == null || target < 1) {
return res;
}
// 先给数组排序,方便后续处理
Arrays.sort(candidates);
dfs(candidates, target, 0, new ArrayDeque<Integer>(), res);
return res;
}
/**
* 做减法
* @param candidates
* @param target 需要加到的目标和
* @param index 数组元素当前下标
* @param path 存储每次选中的元素
* @param ans 最终的结果
*/
private void dfs(int[] candidates, int target, int index, Deque<Integer> path,
List<List<Integer>> res) {
// 当目标值减到0时,说明此时选择的数字满足要求
if (target == 0) {
res.add(new ArrayList(path));
return ;
}
for (int i = index; i < candidates.length; i++) {
// 如果之前的剩余的和减去当前数字小于0,则不符合要求,直接跳出循环
if (target - candidates[i] < 0) {
break;
}
// 如果当前数字跟前一个数字相同,则跳过当前数字,因为前一个数字已经选中了
if (i > index && candidates[i] == candidates[i - 1]) {
continue;
}
path.addLast(candidates[i]);
// 开始尝试下一个位置的数
dfs(candidates, target - candidates[i], i + 1, path, res);
path.removeLast();
}
}
代码参考自:https://leetcode-cn.com/problems/combination-sum-ii/solution/hui-su-suan-fa-jian-zhi-python-dai-ma-java-dai-m-3/