【陪伴式刷题】Day 23|回溯|39.组合总和(Combination Sum)

刷题顺序按照代码随想录建议

题目描述

英文版描述

Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target . You may return the combinations in any order.

The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the

frequency

of at least one of the chosen numbers is different.

The test cases are generated such that the number of unique combinations that sum up to target is less than 150 combinations for the given input.

Example 1:

Input: candidates = [2,3,6,7], target = 7 Output: [[2,2,3],[7]] Explanation: 2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times. 7 is a candidate, and 7 = 7. These are the only two combinations.

Example 2:

Input: candidates = [2,3,5], target = 8 Output: [[2,2,2,2],[2,3,3],[3,5]]

Example 3:

Input: candidates = [2], target = 1 Output: []

Constraints:

  • 1 <= candidates.length <= 30
  • 2 <= candidates[i] <= 40
  • All elements of candidates are distinct.
  • 1 <= target <= 40

英文版地址

leetcode.com/problems/co...

中文版描述

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

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

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

示例 1:

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

示例 2:

ini 复制代码
输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]

示例 3:

ini 复制代码
输入: candidates = [2], target = 1
输出: []

提示:

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

中文版地址

leetcode.cn/problems/co...

解题方法

递归法

ini 复制代码
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        backTracking(candidates, target, 0);
        return result;
    }

    List<List<Integer>> result = new ArrayList<>();
    List<Integer> level = new ArrayList<>();

    private void backTracking(int[] candidates, int target, int startIndex) {
        if (candidates == null || candidates.length == 0 || target < 0) {
            return;
        }
        if (target == 0) {
            result.add(new ArrayList<>(level));
            return;
        }
        for (int i = startIndex; i < candidates.length; i++) {
            level.add(candidates[i]);
            backTracking(candidates, target - candidates[i], i);
            level.remove(level.size() - 1);
        }
    }
}

复杂度分析

官方给出的答案如下(反正我没看懂。。。欢迎有懂的朋友评论区踢我):

  • 时间复杂度:O(S),其中 S 为所有可行解的长度之和,从分析给出的搜索树我们可以看出时间复杂度取决于搜索树所有叶子节点的深度之和,即所有可行解的长度之和。在这题中,我们很难给出一个比较紧的上界,我们知道 O(n×2^n)是一个比较松的上界,即在这份代码中,n 个位置每次考虑选或者不选,如果符合条件,就加入答案的时间代价。但是实际运行的时候,因为不可能所有的解都满足条件,递归的时候我们还会用 target−candidates[idx]≥0 进行剪枝,所以实际运行情况是远远小于这个上界的。
  • 空间复杂度:O(target)。除答案数组外,空间复杂度取决于递归的栈深度,在最差情况下需要递归 O(target) 层。
相关推荐
缪懿6 分钟前
javaee:多线程-锁策略和常见JUC
java·java-ee
郝学胜-神的一滴7 分钟前
[ 力扣 1124 ] 解锁最长良好时段问题:前缀和+哈希表的优雅解法
java·开发语言·数据结构·python·算法·leetcode·散列表
戴西软件8 分钟前
戴西CAxWorks.VPG车辆工程仿真软件|假人+座椅双调整 汽车仿真效率直接拉满
java·开发语言·人工智能·python·算法·ui·汽车
Pentane.14 分钟前
力扣HOT100:T.1 两数之和|循环遍历算法笔记及打卡(12/100)
c++·笔记·算法·leetcode
skiy15 分钟前
Spring WebFlux:响应式编程
java·后端·spring
FeBaby16 分钟前
使用mat 分析java OOM问题
java·开发语言
indexsunny29 分钟前
互联网大厂Java面试实战:基于微服务与云原生的电商场景问答解析
java·数据库·spring boot·docker·微服务·云原生·kubernetes
_深海凉_30 分钟前
LeetCode热题100-爬楼梯
算法·leetcode·职场和发展
小明的IT世界30 分钟前
编程智能体为何能让LLM在实际工作中表现更好
java·开发语言·人工智能·ai编程