持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情
39. 组合总和
题目分析
题目给出一个无重复元素的整数数组和一个目标整数,要求找出数组中可以使数字和为目标数的所有不同组合,并以列表形式返回。
这道题与上次组合题目的区别在于,数组中同一个数字可以无限制重复被选取。并且,题目对数组的数值进行限制(毕竟出现0就不好了)
这道题同样使用回溯算法的方式解决。
解题
由于上次我们已经做过类似的题目,这次就不再分析回溯的总体方式。
直接进行回溯三部曲:
- 递归函数的参数
对于这道题,我设定了两个参数,一个是横向循环for循环时的起始位置,另一个是循环过程中累加的和。
- 回溯函数终止条件
由于这道题没有限制取出的个数,所以并不能判断叶子节点为终止。这道题终止条件是当和等于目标值的时候收集结果,当和大于目标值的时候结束。
- 单层搜索的过程
横向for循环从起始值开始搜索整个集合,纵向通过递归向下进行遍历,注意本题元素可重复选取。
代码如下;
var combinationSum = function(candidates, target) {
const res = [],path = []
candidates.sort((a,b) => a - b)
backstrack(0,0)
return res
function backstrack(j,sum) {
if(sum === target) {
res.push(Array.from(path))
return
}
for(let i = j;i < candidates.length;i++) {
const n = candidates[i]
if(n > target - sum) break
path.push(n)
sum += n
backstrack(i,sum)
path.pop()
sum -= n
}
}
};
从上面的代码可以看出,与上一道组合题相比,不同的点在于终止条件的判断以及回溯时i并不加一。
上面的代码已经进行剪枝操作,当和大于目标值时不进行递归操作。