分享完回溯解决组合问题、子集问题、全排列问题和分割问题,这次分享leetcode上组合总和的第一道题,下面先给出回溯代码模板。
private void backtracking(参数1,参数2,...){
if(递归终止条件){
收集结果;
return;
}
for(遍历集合){
处理;
backtracking(参数1,参数2,...); // 递归;
回溯;
}
}
组合总和
给你一个无重复元素的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的所有不同组合,并以列表形式返回。你可以按任意顺序返回这些组合。candidates 中的同一个数字可以无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
示例 1:
输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。7也是一个候选,7 = 7。仅有这两种组合。
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
int sum = 0;
public List<List<Integer>> combinationSum(int[] candidates, int target) {
backtracking(candidates, 0, target);
return ans;
}
private void backtracking(int[] candidates, int startIndex, int target){
if(sum > target){
return;
}
if(sum == target){
ans.add(new ArrayList<>(path));
return;
}
for(int i = startIndex;i < candidates.length;i++){
sum += candidates[i];
path.add(candidates[i]);
backtracking(candidates, i, target);
sum -= candidates[i];
path.remove(path.size() - 1);
}
}
}
首先定义ans集合用于收集符合要求的组合,定义path收集for循环遍历到的元素,如果path中所有元素的组合符合要求,将其放入到ans集合中。定义sum用于记录path中的所有元素的和。定义combinationSum方法,调用backtracking收集所有符合条件的组合,并返回ans。
以上述示例说明整个代码的执行过程,进入backtracking,sum等于0,不满足两个if判断,进入for循环,startIndex为0,将元素2加入到path中,path为[2],sum为2,题目要求元素可以重复使用,所以传递backtracking的第二个参数时,传递当前遍历元素的下标i,使得下一个backtracking的for循环从上一个backtracking遍历过的元素开始,而不是跳过该元素,进入下一个backtracking中,sum不满足两个if条件,进入for循环,startIndex为0,将元素2加入到path中,此时path为[2, 2],sum为4,进入下一个backtracking,sum不满足两个if判断,进入for循环,startIndex从0开始,将元素2加入到path中,此时path为[2, 2, 2],sum为6,进入下一个backtracking,sum不满足两个if判断,进入for寻魂,startIndex为0开始,将元素2加入到path中,此时path为[2, 2, 2, 2],sum等于8,进入下一个backtracking,此时sum(8) > target(7),返回上一个backtracking,将元素2从path中移除,path为[2, 2, 2],sum为6,for循环继续,i++,将元素3加入path,path为[2, 2, 2, 3],sum为9,进入下一个backtracking,sum(9) > target(7),递归返回上一个backtracking,将元素3从path中移除,path为[2, 2, 2],sum为6,for循环继续,i++,将元素6加入path中,path为[2, 2, 2, 6],sum为12,递归进入下一个backtracking,sum(12) > target(7),递归返回上一个backtracking,将元素6从path中移除,path为[2, 2, 2],sum为6,将元素7加入到path中,path为[2, 2, 2, 7],sum为13,递归进入下一个backtracking,sum(13) > target(7),递归返回上一个backtracking,将元素7从path中移除,path为[2, 2, 2],for循环继续,i++等于数组长度循环结束。递归返回上一个backtracking,将元素2从path中移除,path为[2, 2],sum等于4,for循环继续,i++,将元素3加入path中,path为[2, 2, 3],sum等于7,递归进入下一个backtracking,sum(7) = target(7),符合条件,将[2, 2, 3]加入ans集合中,递归返回上一个backtracking,将元素3从path中移除,path为[2, 2],sum等于4,for循环继续,将元素6加入path中,path为[2, 2, 6],sum等于10,递归进入下一个backtracking,sum(10) > target(7),递归返回上一个backtracking,将元素6从path中移除,path为[2, 2],sum等于4,for循环继续,将元素7加入path中,path为[2, 2, 7],sum等于11,递归进入下一个backtracking,sum(11) > target(7),递归返回上一个backtracking,将元素7从path中移除,path为[2, 2],sum等于4,for循环继续,i++等于数组长度,for循环结束,递归返回上一个backtracking。如此重复,即可得到所有符合要求的组合。