39.组合总和
● 虽然没有限制组合的个数,但是由于对targetSum有要求,也是一种限制
● [2,3,5]中取数,取了2之后,继续在[2,3,5]中取数,和之前不一样的是不需要从下一个数字取了。
class Solution {
List<Integer> path=new ArrayList<>();
List<List<Integer>> result=new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
backtracking(candidates,target,0,0);
return result;
}
public void backtracking(int[] candidates,int target,int sum,int startIndex){
if(sum>target){
return;
}
if(sum==target){
result.add(new ArrayList<>(path));
return;
}
for(int i=startIndex;i<candidates.length;i++){
sum=sum+candidates[i];
path.add(candidates[i]);
//startIndex不用再从下一个开始
backtracking(candidates,target,sum,i);
sum=sum-candidates[i];
path.removeLast();
}
}
}
40.组合总和2
本题的难点在于区别2中:集合(数组candidates)有重复元素,但还不能有重复的组合。
本题涉及到一个问题了:去重。
“使用过”在这个树形结构上是有两个维度的,一个维度是同一树枝上使用过,一个维度是同一树层上使用过
● 同一树枝上的相同元素可以重复取
● 同一层上的相同元素不可以重复取
● 对candidates数组进行排序
● 难点:怎么识别同一层上的元素已经取过了?
○ 将数组排序,如果是相同的元素一定相邻。
class Solution {
List<Integer> path=new ArrayList<>();
List<List<Integer>> result=new ArrayList<>();
boolean[] used;
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
//对candidates排序
Arrays.sort(candidates);
backtracking(candidates, target,0,0);
return result;
}
public void backtracking(int[] candidates,int target,int sum,int startIndex){
if(sum>target){
return;
}
if(sum==target){
result.add(new ArrayList<>(path));
return;
}
for(int i=startIndex;i<candidates.length;i++){
//对已有序的数组来说,相同的元素一定相邻
if(i>startIndex&&candidates[i]==candidates[i-1]){
continue;
}
sum=sum+candidates[i];
path.add(candidates[i]);
backtracking(candidates,target,sum,i+1);
sum=sum-candidates[i];
path.removeLast();
}
}
}