回溯——40.组合总和II

跟39相比,40主要添加了两个要求:

  1. 每个数字在每个组合中只能使用一次。
  2. 解集不能包含重复的组合。 

最简单的想法肯定是和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参加下一层的回溯中,否则体现在回溯树中,就是如下:

 

posted @ 2021-12-07 20:56  Mirror559  阅读(29)  评论(0)    收藏  举报