[LeetCode] Combination Sum 组合之和
Given a set of candidate numbers (candidates
) (without duplicates) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sums to target
.
The same repeated number may be chosen from candidates
unlimited number of times.
Note:
- All numbers (including
target
) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates =[2,3,6,7],
target =7
, A solution set is: [ [7], [2,2,3] ]
Example 2:
Input: candidates = [2,3,5],
target = 8,
A solution set is:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
像这种结果要求返回所有符合要求解的题十有八九都是要利用到递归,而且解题的思路都大同小异,相类似的题目有 Path Sum II,Subsets II,Permutations,Permutations II,Combinations 等等,如果仔细研究这些题目发现都是一个套路,都是需要另写一个递归函数,这里我们新加入三个变量,start记录当前的递归到的下标,out为一个解,res保存所有已经得到的解,每次调用新的递归函数时,此时的target要减去当前数组的的数,具体看代码如下:
注意几个点 这里因为需要重复用到元素 每次递归后元素要重新使用,所以我们不能用Boolean[] visited的情况,考虑到要提供一个标记,结合上一题这里也是start标记,那么start怎么看呢,我们先给数组排好序i,每次递归进去
以上面例子为例;
2 , 2 , 2 ,2 i=0; i=0; i=0; i=0; 让start = 0; = 0; =0; =0;
2 , 2, 2 , 3 i=0; i=0; i=0; i=1;
2 , 2, 2, 5, i=0; i=0; i=0; i=2;
2 , 2, 3, 2, i=0; i=0; i=1; i=0;
2, ,2 , 3, 3, i=0; i=0; i=1; i=1;
2, 2, 3, 5 i=0; i=0; i=1; i=2;
3 开头, 就让start= 1; 3, 。。。。所以让start= i;让递归从包含这个值以及之后的值开始;
这里还要考虑当target < 0 后怎么办 答案给的是用if(data[i] < target) 这样循环到这都直接返回了
思考这类题的逻辑就是 一个值包含下面各种值的可能
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> combinations = new ArrayList<>();
List<Integer> combinationList = new ArrayList<>();
Arrays.sort(candidates);
help(combinations, combinationList, 0, target, candidates);
return combinations;
}
private void help(List<List<Integer>> combinations, List<Integer> combinationList,
int start, int target, final int[] candidates){
if(target == 0){
combinations.add(new ArrayList<>(combinationList));
return;
}
for(int i=start; i<candidates.length; i++){
if(candidates[i] <= target){
combinationList.add(candidates[i]);
help(combinations, combinationList, i,
target - candidates[i],candidates);
combinationList.remove(combinationList.size() - 1);
}
}
}
}
自己第二次写
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<Integer> list = new ArrayList<>();
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(candidates);
help(0, result, list, target, candidates);
return result;
}
private void help(int start, List<List<Integer>> result, List<Integer> list, int target,
int[] candidates){
if(target == 0){
result.add(new ArrayList(list));
return;
}
for(int i = start; i < candidates.length; i++){
if(target < 0)
break;
list.add(candidates[i]);
help(i, result, list, target - candidates[i] , candidates);
list.remove(list.size()-1);
}
}
}