40. 组合总和 II
https://leetcode-cn.com/problems/combination-sum-ii/
解法一:回溯
类似 39.组合总和
区别在于不能重复取,因此递归的起点由39题中的i变成i+1。此外还要判断是同一层递归的重复还是不同层递归,若是同一层,重复则跳过,不同层则不需要跳过,判断依据为:
i-1 >= start
,若符合说明i-1与i是同一层,若还有candidates[i] == candidates[i-1]
,则跳过i
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
self.res = []
tmpList = []
candidates.sort()
self.backtrack(tmpList, candidates, target, 0)
return self.res
def backtrack(self, tmpList, candidates, remain, start):
if remain < 0:
return
elif remain == 0:
self.res.append(list(tmpList))
else:
for i in range(start, len(candidates)):
#跳过重复
if i-1 >= start and candidates[i] == candidates[i-1]:
continue
#下一层递归起点为i+1
self.backtrack(tmpList + [candidates[i]], candidates, remain - candidates[i], i+1)
2020.3.26 因为每层对[start, n)
进行递归,因此判断i-1是否在[start, n)
中即可知道是否同层
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
def dfs(tmp, sum, start):
if sum > target:
return
elif sum == target:
res.append(list(tmp))
return
for i in range(start, n):
num = candidates[i]
if i-1 >= start and num == candidates[i-1]: #已经使用过了,跳过,去重
continue
dfs(tmp + [num], sum + num, i+1) #每个数字只用一次
candidates.sort()
n = len(candidates)
res = []
dfs([], 0, 0)
return res
最后更新于