LeetCode 第39题 组合数和


给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:

输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]

思路: 回溯法搜索(排列树)
step 1 : 排序
step 2 : 回溯搜索 , 将每一个可行解保存到res集合中

剪枝方案:
1.经过排序后 如 2, 3, 6 ,7
先选一个数,如果这个数加上已经在可行解中的数没有超过target 如 (sum:4)+2 <= (target:7)说明这个数有可能产生可行解(sum=target)
将其加入到可行解中(2,2,2).
如果这个数加上已经在可行解中的数超过了target 如 (sum:6)+2 <= (target:7)说明这个数已经不可能产生可行解了
2.每次选择的数都是从candidates中选择的[2,3,6,7](遍历方式,从小到大)
如果2+sum>target , 那么还有必要尝试选择3,6,7吗?显然没有必要了.
3.根据题目要求.产生的可行解也是递增的
如[2,2,3] 可以
[3,2,2] 不可以
[3,2,3] 不可以
也就是说,如果当前选择的数为3,那么下一层就不能选择2
如果当前选择的数为6,那么下一层就不能选择2,3 (通过遍历时对起始下标的控制能很好的解决这个问题)


 1 class Solution39 {
 2 
 3   int target;
 4   private List<List<Integer>> res = new ArrayList<>();
 5 
 6   public List<List<Integer>> combinationSum(int[] candidates, int target) {
 7     if (candidates == null || candidates.length == 0) {
 8       return res;
 9     }
10     this.target = target;
11     Arrays.sort(candidates);
12     search(candidates, 0, new ArrayList<>(),0);
13     return res;
14   }
15 
16   private void search(int[] candidates, int sum, List<Integer> list,int pos) {
17     if (sum <= target) {
18       if (sum == target) {
19         res.add(new ArrayList<>(list));
20         return;
21       }
22       for (int i = pos; i < candidates.length; i++) {
23         if (sum + candidates[i] <= target) {
24           list.add(candidates[i]);
25           search(candidates, sum + candidates[i], list,i);
26           list.remove((Integer) candidates[i]);
27         } else {
28           break;
29         }
30       }
31     }
32   }
33 }

 

猜你喜欢

转载自www.cnblogs.com/rainbow-/p/10347410.html