加起来和为目标值的组合–去重剪枝
这道算法需要理解DFS深度优先遍历。
深度优先搜素:
采用递归方法,先沿着一条路搜到底,再递归会上一个节点,沿另一个方向搜索,依次类推。
思想:一直往深处走,直到找到解或者走不下去为止。
结合这道题,加起来和为目标值的组合。首先我们想到肯定要遍历,结合遍历到的数加起来是否等去目标值,但问题是一个数组中可能有多个组合等于目标值,结果中还不能包含重复组合,所以这道题非常适合用DFS思想来做。
我们判断点在遍历到的数是否<=target,如果大于肯定错误,小于则加入到一个list中,在递归调用方法,注意记住要把遍历的指针加1,和target减递归调用前指针指向的数,知道target==0。先把代码放下,结合代码看:
ArrayList<ArrayList> arrlist = new ArrayList<>();
public ArrayList<ArrayList<Integer>> combinationSum2(int[] num, int target) {
if(num == null || num.length == 0 ||target<= 0){
return arrlist;
}
ArrayList<Integer> temp = new ArrayList<>();
//先给数组做了个排序,下面遍历的时候如果小于target,直接返回就行了
Arrays.sort(num);
targetSum(num,0,num.length,target,temp);
return arrlist;
}
public void targetSum(int[] num,int start,int end,int target,ArrayList<Integer> temp){
//当递归到target==0,证明该组合==target
if(target == 0){
ArrayList<Integer> list = new ArrayList<>(temp);
arrlist.add(list);
return;
}
//重点理解这个循环
for(int i = start; i < end; i++){
//因为题目要求结果不能有重复的组合 ,好好理解下.
if(i > start && num[i] == num[i-1]) continue; //去重
//当该值小于target时,证明可能有解
if(num[i] <= target){
temp.add(num[i]);
//递归调用,一步一步叠加,知道target==0,加入list
targetSum(num,i+1,num.length,target-num[i],temp);
//条件满足时,去掉该节点继续搜寻下一个数会不会满足条件
temp.remove(temp.size()-1); //减枝
}else{
//大于target 证明肯定没有解,直接返回
return;
}
}
}