40. 组合总和 II

2 阅读1分钟

40. 组合总和 II

给定一个候选人编号的集合 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