39. 组合总和
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。
示例 1:
- 输入:candidates = [2,3,6,7], target = 7
- 输出:[[2,2,3],[7]]
- 解释:2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。7 也是一个候选, 7 = 7 。仅有这两种组合。
分析: 看到这种要列出所有结果的题,一般能想到的就是回溯。因此需要采用递归的方法去求解,在这个过程中,需要注意的是递归终止的条件有两个,一个是遍历到底部了,也就是递归层数等于给定数组长度,另一个是当前target为0,因为我们每次递归就将target减去所用的一个数字。
本题依据题意,还需要注意的是数字是可以重复使用的,因此我们在一次递归中,既可以选择跳过当前数字,也可以使用当前数字,如果使用的话,就要加上回撤的操作。
代码
func combinationSum(candidates []int, target int)( ans [][]int) {
var comb []int
var dfs func(target, idx int)
dfs = func(target, idx int) {
//递归终止条件
if idx == len(candidates) {
return
}
if target == 0 {
ans = append(ans, append([]int(nil), comb...))
return
}
//可以选择不用当前这个数字
dfs(target, idx+1)
//可以选择使用当前数字
if target-candidates[idx] >= 0 {
//选择
comb = append(comb, candidates[idx])
dfs(target-candidates[idx], idx)
//撤销选择
comb = comb[:len(comb)-1]
}
}
dfs(target,0)
return
}