LeetCode-39. 组合总和【数组 回溯】

题目描述:

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

示例 1:

输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。
示例 2:

输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]
示例 3:

输入: candidates = [2], target = 1
输出: []

提示:

1 <= candidates.length <= 30
2 <= candidates[i] <= 40
candidates 的所有元素 互不相同
1 <= target <= 40

解题思路一:回溯,回溯三部曲

  1. 递归函数参数
    这里依然是定义两个全局变量,二维数组result存放结果集,数组path存放符合条件的结果。(这两个变量可以作为函数参数传入)

首先是题目中给出的参数,集合candidates, 和目标值target。

此外我还定义了int型的sum变量来统计单一结果path里的总和,其实这个sum也可以不用,用target做相应的减法就可以了,最后如何target==0就说明找到符合的结果了,但为了代码逻辑清晰,我依然用了sum。

本题还需要startIndex来控制for循环的起始位置,对于组合问题,什么时候需要startIndex呢?

我举过例子,如果是一个集合来求组合的话,就需要startIndex,例如:77.组合 (opens new window),216.组合总和III (opens new window)。

如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,例如:17.电话号码的字母组合
2. 递归终止条件
在如下树形结构中:
在这里插入图片描述
从叶子节点可以清晰看到,终止只有两种情况,sum大于target和sum等于target。

sum等于target的时候,需要收集结果,代码如下:

  1. 单层搜索的逻辑
    单层for循环依然是从startIndex开始,搜索candidates集合。

注意本题和77.组合 (opens new window)、216.组合总和III (opens new window)的一个区别是:本题元素为可重复选取的。

如何重复选取呢,看代码,注释部分:

class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        res = []
        candidates.sort()
        self.backtracking(candidates, target, 0, [], res)
        return res

    def backtracking(self, candidates, target, index, path, res):
        if target == 0:
            res.append(path[:])
            return
        for i in range(index, len(candidates)):
            if target - candidates[i] < 0:
                break
            path.append(candidates[i])
            self.backtracking(candidates, target - candidates[i], i, path, res)
            path.pop()

时间复杂度:O(S) 其中 S 为所有可行解的长度之和。
空间复杂度:O(target)。除答案数组外,空间复杂度取决于递归的栈深度,在最差情况下需要递归 O(target) 层。

解题思路二:0


时间复杂度:O(n)
空间复杂度:O(n)

解题思路三:0


时间复杂度:O(n)
空间复杂度:O(n)

相关推荐

  1. 回溯Leetcode 39. 组合总和【中等】

    2024-04-06 18:56:06       19 阅读
  2. 组合总和(Lc39)——排序+剪枝+回溯

    2024-04-06 18:56:06       9 阅读
  3. LeetCode 0039.组合总和回溯 + 剪枝

    2024-04-06 18:56:06       12 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-06 18:56:06       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-06 18:56:06       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-06 18:56:06       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-06 18:56:06       20 阅读

热门阅读

  1. Go语言时间编程

    2024-04-06 18:56:06       62 阅读
  2. python 三位数字黑洞

    2024-04-06 18:56:06       18 阅读
  3. C++继承

    C++继承

    2024-04-06 18:56:06      24 阅读