【LeetCode】40. 组合总和 II

1 问题

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

2 答案

自己写的不对,参照上一题写的,没有删去重复的集合列表

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

你可能感兴趣的:(LeetCode,Python,leetcode,算法)