给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
- 所有数字(包括
target)都是正整数。
- 解集不能包含重复的组合。
示例 1:
1 2 3 4 5 6
| 输入:candidates = [2,3,6,7], target = 7, 所求解集为: [ [7], [2,2,3] ]
|
示例 2:
1 2 3 4 5 6 7
| 输入:candidates = [2,3,5], target = 8, 所求解集为: [ [2,2,2,2], [2,3,3], [3,5] ]
|
提示:
1 <= candidates.length <= 30
1 <= candidates[i] <= 200
candidate 中的每个元素都是独一无二的。
1 <= target <= 500
由于 candidates 是无序的,只能暴力搜索全部的解。考虑剪枝,先将 candidates 数组排序,在搜索的过程中如果得到的当前总和大于 target ,那么后面的元素总和都不用尝试(由于数组递增,它们的总和比大于当前总和)。
数字可以被重复选取代表下一次递归时,还可以取当前选取的数字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Solution { List<List<Integer>> ans = new ArrayList<List<Integer>>();
public List<List<Integer>> combinationSum(int[] candidates, int target) { Arrays.sort(candidates); dfs(0, target, candidates, new ArrayDeque<Integer>()); return ans; }
private void dfs(int start, int target, int[] candidates, ArrayDeque<Integer> path){ int end = candidates.length - 1; if(target == 0){ ans.add(new ArrayList(path)); return; } for(int i = 0; start + i <= end; i++){ int cur = candidates[start + i]; if(target - cur < 0){ break; }else{ path.addLast(cur); dfs(start + i, target - cur, candidates, path); path.removeLast(); } } } }
|