回溯——40.组合总和II
跟39相比,40主要添加了两个要求:
- 每个数字在每个组合中只能使用一次。
- 解集不能包含重复的组合。
最简单的想法肯定是和39类似,主要是用HashSet来存储结果,这样可以直接去重,但是这样会超时。
因此函数做出了以下改动:
1 private void backtracking(int[] candidates, int target, int startIndex, int sum) { 2 if (sum == target) { 3 result.add((ArrayList) path.clone()); 4 } 5 6 // && 剪枝: 7 //path中的下一个元素必须 <= target - sum,否则在有序正整数数组中将不可能达成sum == target 8 for (int i = startIndex; i < candidates.length && candidates[i] <= target - sum; ++i) { 9 //遍历到的元素在本次回溯中已经加入过path中,需要跳过,否则将造成重复 10 if (i > startIndex && candidates[i-1] == candidates[i]) { 11 continue; 12 } 13 path.add(candidates[i]); 14 // i+1 :每个数字在每个组合只能用一次 15 backtracking(candidates, target, i+1, sum+candidates[i]); 16 path.remove(path.size() - 1); 17 } 18 }
对于代码:
if (i > startIndex && candidates[i-1] == candidates[i]) { continue; }
这是因为数组中可能有重复的数,对于回溯树中的一条路来说,要保证其统计的结果没有重复,那么在回溯树当前这一层中,就不能将两个相同的元素加入到path参加下一层的回溯中,否则体现在回溯树中,就是如下:


浙公网安备 33010602011771号