DFS+回溯专题 - leetcode39. Combination Sum/40. Combination Sum II/216. Combination Sum III

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a786150017/article/details/82978421

39. Combination Sum

题目描述

给定候选数集(无重复)和目标值target,找出候选集中数字累加和为target的组合。(候选集中数字可以用无限次)

例子

Example 1:
Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
[7],
[2,2,3]
]
Example 2:
Input: candidates = [2,3,5], target = 8,
A solution set is:
[
[2,2,2,2],
[2,3,3],
[3,5]
]

思路
注意列表中的数可以用很多次

回溯法。由于组合中的数字要按序排列,我们先将集合中的数排序。依次把数字放入组合中,因为所有数都是正数,如果当前和已经超出目标值,则放弃;如果和为目标值,则加入结果集;如果和小于目标值,则继续增加元素。由于结果集中不允许出现重复的组合,所以增加元素时只增加当前元素及之后的元素。

解法
回溯。

class Solution(object):
    def combinationSum(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        candidates.sort()
        res = []
        self.dfs(candidates, target, [], res)
        return res
    
    def dfs(self, candidates, target, path, res):
        if target == 0:
            res.append(path[:])
            return
        
        for i in range(len(candidates)):
            if candidates[i] > target:
                break
            self.dfs(candidates[i:], target - candidates[i], path + [candidates[i]], res)

40. Combination Sum II

题目描述

给定候选数集(有重复)和目标值target,找出候选集中数字累加和为target的组合。(候选集中数字只能用一次)

例子

Example 1:
Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
Example 2:
Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
[1,2,2],
[5]
]

思路
在上一题的基础上
改动1 - 排序后,和上一个元素重复则continue;
改动2 - 每个元素只能用1次

解法
回溯。

class Solution(object):
    def combinationSum2(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        candidates.sort()
        res = []
        self.dfs(candidates, target, [], res)
        return res
    def dfs(self, candidates, target, path, res):
        if target == 0:
            res.append(path[:])
            return
            
        for i in range(len(candidates)):
            if candidates[i] > target:
                break
            if i > 0 and candidates[i] == candidates[i-1]:
                continue
            self.dfs(candidates[i+1:], target - candidates[i], path + [candidates[i]], res)

216. Combination Sum III

题目描述

k个数的和为n,数只能取1-9,且只能取1次。

例子

Example 1:
Input: k = 3, n = 7
Output: [[1,2,4]]
Example 2:
Input: k = 3, n = 9
Output: [[1,2,6], [1,3,5], [2,3,4]]

思路
类似leetcode39

解法
DFS

class Solution(object):
    def combinationSum3(self, k, n):
        """
        :type k: int
        :type n: int
        :rtype: List[List[int]]
        """
        res = []
        self.dfs(k, n, 1, [], res)
        return res
    
    def dfs(self, k, n, lower, path, res):
        if n == 0 and k == 0:
            res.append(path[:])
            return
        
        for num in range(lower, 10):
            if num > n or k < 0:
                break
            self.dfs(k - 1, n - num, num+1, path + [num], res)

猜你喜欢

转载自blog.csdn.net/a786150017/article/details/82978421