1、题目描述
https://leetcode-cn.com/problems/combination-sum/
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
- candidates 中的数字可以无限制重复被选取。
- 所有数字(包括 target)都是正整数。 解集不能包含重复的组合。
输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[[7],
[2,2,3]]
输入:candidates = [2,3,5], target = 8,
所求解集为:
[[2,2,2,2],
[2,3,3],
[3,5]]
- 1 <= candidates.length <= 30
- 1 <= candidates[i] <= 200
- candidate 中的每个元素都是独一无二的。
- 1 <= target <= 500
2、代码详解
写法一:target从target不断减到0
class Solution:
def combinationSum(self, candidates, target):
if not candidates:
return []
n = len(candidates)
res = []
candidates.sort()
def helper(i, tmp, target): # 下一加和索引i,当前已加和数组tmp,下一目标target(不断减)
# 若target==0(target减后为0),说明当前和满足条件,将当前加和数组tmp加入res,并return
if target == 0:
res.append(tmp)
return
# 剪枝 因为已经将candidates排序,所以当下一目标小于下一待加和数时,return。
# 并且当下一待加和索引i==n时,return。
# 为了防止数组越界,将条件i==n放在target<candidates[i]之前,进行截断。
if i == n or target < candidates[i]:
return
helper(i, tmp + [candidates[i]], target - candidates[i]) # 因为可重复调用元素,继续重复调用自身。
helper(i + 1, tmp, target) # 调用数组中下一元素,寻找新答案
helper(0, [], target)
return res
同类写法二:tmp_sum从0加到target
class Solution:
def combinationSum(self, candidates, target):
candidates.sort()
n = len(candidates)
res = []
def helper(i, tmp, tmp_sum):
if tmp_sum > target or i == n:
return
if tmp_sum == target:
res.append(tmp)
return
helper(i, tmp + [candidates[i]], tmp_sum + candidates[i])
helper(i+1, tmp, tmp_sum)
helper(0, [], 0)
return res