题解
回溯法+排序剪枝
为了对算法进行剪枝处理,首先对 c a n d i d a t e s candidates candidates排序
-
特判,若 c a n d i d a t e s candidates candidates为空,则返回 [ ] [] []
-
回溯函数 h e l p e r ( ) helper() helper(),传入参数:下一加和索引 i i i,当前已加和数组 t m p tmp tmp,下一目标 t a r g e t target target
- 若 t a r g e t = = 0 target==0 target==0,说明当前和满足条件,将当前加和数组 t m p tmp tmp加入 r e s res res,并return。
- 剪枝 因为已经将 c a n d i d a t e s candidates candidates排序,所以当下一目标小于下一待加和数时,return。并且当下一待加和索引 i = = n i==n i==n时,return。为了防止数组越界,将条件 i = = n i==n i==n放在 t a r g e t < c a n d i d a t e s [ i ] target<candidates[i] target<candidates[i]之前,进行截断。
- 因为可重复调用元素,所以 h e l p e r ( i , t m p + [ c a n d i d a t e s [ i ] , t a r g e t − c a n d i d a t e s [ i ] ] ) helper(i,tmp+[candidates[i],target-candidates[i]]) helper(i,tmp+[candidates[i],target−candidates[i]]),继续重复调用自身。
- 调用数组中下一元素,寻找新答案。 h e l p e r ( i + 1 , t m p , t a r g e t ] ) helper(i+1,tmp,target]) helper(i+1,tmp,target])。
-
执行 h e l p e r ( 0 , [ ] , t a r g e t ) helper(0,[],target) helper(0,[],target),并返回 r e s res res
复杂度分析
- 时间复杂度: O ( 2 n ) O\left(2^{n}\right) O(2n)
- 空间复杂度: O ( 1 ) O(1) O(1)
Python
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
if(not candidates):
return []
n=len(candidates)
res=[]
candidates.sort()
def helper(i,tmp,target):
if(target==0):
res.append(tmp)
return
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
剪枝效果,有点好!