给你一个 无重复元素 的整数数组
candidates
和一个目标整数target
,找出candidates
中可以使数字和为目标数target
的 所有 **不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates
中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。对于给定的输入,保证和为
target
的不同组合数少于150
个。
解法 回溯剪枝
思路
先想一下递归需要哪些参数呢?每次递归的 path
,然后累加或者累减的参数,其次就是每次开始的索引。
为什么需要索引?如果传递索引,那么每次都是从 0
开始循环递归,这样会造成很多重复组合。
接下来就是递归结束条件,如果累加或累减到 target
或者 0
则放入结果集,退出递归。这里还可以稍微剪一下枝,数组里都是正数,如果当前结果不支持达成目标,那么后续的都不可能,所以也可以退出。
下面就是循环要从 start
开始,这样避免和很多重复组合,递归的时候传入当前 i
这样是为了重复选择这个数。
代码
function combinationSum(candidates: number[], target: number): number[][] {
const result = [];
const dfs = (path, start, rest) => {
if (rest === 0) {
result.push([...path]);
return;
}
if (rest < 0) {
return;
}
for (let i = start; i < candidates.length; i++) {
path.push(candidates[i]);
dfs(path, i, rest - candidates[i]);
path.pop();
}
};
dfs([], 0, target);
return result;
};
时空复杂度
时间复杂度:O(2^target)
空间复杂度:O(target)