给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意: 解集不能包含重复的组合。
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort()
r=len(candidates)
re=[]
s=[]
if sum(candidates)<target:
return []
def dfs(l,target,r):
if target==0:
temp=sorted(s)
if temp not in re:
re.append(temp[:])
return
if target<0:
return
for i in range(l,r):
if candidates[i]>target:
break
s.append(candidates[i])
dfs(i+1,target-candidates[i],r)
s.pop()
dfs(0,target,r)
return re
这里看我的代码,需要考虑如果出现两个同样数字比如1,1,2,3,4的话,进行for循环时,先是以1为首位,然后第二次循环也是以1为首位,这样两者完全一样,所以这里最关键的一点就是如果两个数字一样要进行一次continue,这样的话最后咱们添加进答案队列也不需要再进行判断,这样可以减少大量耗时
from typing import List
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort()
res = []
path = []
def dfs(start: int, remain: int):
if remain == 0:
res.append(path[:])
return
for i in range(start, len(candidates)):
if candidates[i] > remain:
break # 剪枝:后续更大,直接退出循环
# 跳过同一层的重复元素
if i > start and candidates[i] == candidates[i-1]:
continue
path.append(candidates[i])
dfs(i + 1, remain - candidates[i]) # 递归时传入 i+1 和更新后的 remain
path.pop()
dfs(0, target)
return res