10-1

40. 组合总和 II

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]

An understandable python solution:

class Solution(object):
    def combinationSum2(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        candidates.sort()                      
        result = []
        self.bfs(candidates, target, 0, [], result)
        return result

    def bfs(self, nums, target, start, path, result):
        if target == 0:
            result.append(path)
            return
        for i in range(start, len(nums)):
            if target < nums[i]:
                break # early stopping
            if i > start and nums[i] == nums[i - 1]:
                continue # avoid duplicating
            self.bfs(nums, target - nums[i], i + 1, path + [nums[i]], result)

分析:

(1)如果说第39题的“组合总和 I”是DFS,那么本题可以看做是BFS(广度优先搜索)。它们的区别在于DFS尽可能地往深度方向搜索,而BFS尽可能地往广度方向搜索。反映在代码中,就是在每次向下递归时,DFS传递的索引是 i ,而BFS传递的索引是 i+1 。

(2)本题代码中的大部分内容均与第39题相同,除(1)中提到的不同之处外,这里还有另外一个不同之处:因为本题中的数字是有可能包含重复的数字的,这也就意味着如果不做处理,结果中可能会包含有重复的组合。如何解决这一问题呢?代码中的以下判断提供了解决这一问题的一种方法:

if i > start and nums[i] == nums[i - 1]:
                continue

如果后面的数字有重复,那就跳过这些重复的数字,从下一个非重复的数字开始继续执行代码。

posted @ 2019-07-10 10:35  mingyu02  阅读(406)  评论(0编辑  收藏  举报