给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]
自己写的不对,参照上一题写的,没有删去重复的集合列表
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
def dfs(candidates, start, size, path, res, target):
if target == 0:
res.append(path)
for index in range(start, size):
if target - candidates[index] < 0:
break
dfs(candidates, index+1, size, path+[candidates[index]], res, target-candidates[index])
res = []
path = []
size = len(candidates)
candidates.sort()
dfs(candidates, 0, size, path, res, target)
return res
稍做修改,加一个判断candidates当前值与前一个是否相同的判断,用于去重
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
def dfs(candidates, start, size, path, res, target):
if target == 0:
res.append(path)
for index in range(start, size):
if target - candidates[index] < 0:
break
if index > start and candidates[index - 1] == candidates[index]: # 加一个判断candidates当前值与前一个是否相同的判断,如果相同,跳过该次循环,进入下一次循环
continue
dfs(candidates, index+1, size, path+[candidates[index]], res, target-candidates[index])
res = []
path = []
size = len(candidates)
candidates.sort()
dfs(candidates, 0, size, path, res, target)
return res
官方解,依然是回溯,如果修改了path,则需要pop()
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
def dfs(begin, path, residue):
if residue == 0:
res.append(path[:])
return
for index in range(begin, size):
if candidates[index] > residue: # 将判断放到循环里面,可以判断更多次,用于剪枝
break
if index > begin and candidates[index - 1] == candidates[index]:
continue
# path.append(candidates[index]) # 这种写法修改了path,所以需要path.pop()
dfs(index + 1, path+[candidates[index]], residue - candidates[index])
# path.pop()
size = len(candidates)
candidates.sort()
res = []
dfs(0, [], target)
return res