【LeetCode笔记】39. 组合总和(中等)

287 阅读2分钟

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
}