diff --git a/problems/0039.组合总和.md b/problems/0039.组合总和.md index 4e1df6c7..5244a1d6 100644 --- a/problems/0039.组合总和.md +++ b/problems/0039.组合总和.md @@ -42,7 +42,7 @@ candidates 中的数字可以无限制重复被选取。 题目中的**无限制重复被选取,吓得我赶紧想想 出现0 可咋办**,然后看到下面提示:1 <= candidates[i] <= 200,我就放心了。 -本题和[77.组合](https://programmercarl.com/0077.组合.html),[216.组合总和III](https://programmercarl.com/0216.组合总和III.html)和区别是:本题没有数量要求,可以无限重复,但是有总和的限制,所以间接的也是有个数的限制。 +本题和[77.组合](https://programmercarl.com/0077.组合.html),[216.组合总和III](https://programmercarl.com/0216.组合总和III.html)的区别是:本题没有数量要求,可以无限重复,但是有总和的限制,所以间接的也是有个数的限制。 本题搜索的过程抽象成树形结构如下: @@ -335,33 +335,32 @@ class Solution: 主要在于递归中传递下一个数字 ```go +var ( + res [][]int + path []int +) func combinationSum(candidates []int, target int) [][]int { - var trcak []int - var res [][]int - backtracking(0,0,target,candidates,trcak,&res) + res, path = make([][]int, 0), make([]int, 0, len(candidates)) + sort.Ints(candidates) // 排序,为剪枝做准备 + dfs(candidates, 0, target) return res } -func backtracking(startIndex,sum,target int,candidates,trcak []int,res *[][]int){ - //终止条件 - if sum==target{ - tmp:=make([]int,len(trcak)) - copy(tmp,trcak)//拷贝 - *res=append(*res,tmp)//放入结果集 + +func dfs(candidates []int, start int, target int) { + if target == 0 { // target 不断减小,如果为0说明达到了目标值 + tmp := make([]int, len(path)) + copy(tmp, path) + res = append(res, tmp) return } - if sum>target{return} - //回溯 - for i:=startIndex;i target { // 剪枝,提前返回 + break + } + path = append(path, candidates[i]) + dfs(candidates, i, target - candidates[i]) + path = path[:len(path) - 1] } - } ```