LeetCode 39.组合总和
组合总和
给你一个无重复元素的整数数组candidates
和一个目标整数target
,找出candidates
中可以使数字和为目标数target
的所有不同组合 ,并以列表形式返回。你可以按任意顺序返回这些组合。
candidates
中的同一个数字可以无限制重复被选取。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于150
个。
输入:candidates = [2,3,6,7], target = 7 |
方法一:回溯
算法思路:
本题和77.组合 (opens new window),216.组合总和III (opens new window)和区别是:本题没有数量要求,可以无限重复,但是有总和的限制,所以间接的也是有个数的限制。
-
确定递归函数的返回值以及参数
除了题中输入
candidates
和target
外,还需要定义sum
来记录path
中的总和。startIndex
的设置(仅针对求组合问题,排列问题不一样):- 如果是一个集合来求组合的话,就需要
startIndex
,如77.组合 (opens new window),216.组合总和III (opens new window)。 - 如果是多个集合取组合,各个集合之间相互不影响,就不需要设置
startIndex
,如17.电话号码的字母组合
- 如果是一个集合来求组合的话,就需要
-
确定终止条件
当
sum
大于等于target
时终止递归,当sum
等于target
时,将path
添加到result
中。if(sum >= target){
if(sum == target){
result.add(new ArrayList<>(path));
}
return;
} -
单层搜索的过程
单层
for
循环依然是从startIndex
开始,搜索candidates
集合。此处需要注意元素可以重复选取。for(int i = startIndex; i < candidates.length; i++){
sum += candidates[i];
path.add(candidates[i]);
backTracking(candidates, target, sum, i);//可以重复选取元素,所以不用i+1
sum -= candidates[i];
path.removeLast();
}
代码实现:
class Solution { |
方法二:剪枝优化
对于排序数组candidates
,当sum + candidates[i] > target
时,后续的数就不需要遍历了,直接break
。
代码实现:
class Solution { |
参考
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Abacteria的学习小站!