【陪伴式刷题】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) 层。
相关推荐
苹果醋37 分钟前
Vue3响应式数据: 深入分析Ref与Reactive
java·运维·spring boot·mysql·nginx
茶猫_17 分钟前
力扣面试题 - 40 迷路的机器人 C语言解法
c语言·数据结构·算法·leetcode·机器人·深度优先
缘友一世24 分钟前
JAVA代理模式和适配器模式
java·代理模式·适配器模式
轻浮j27 分钟前
Sentinel底层原理以及使用算法
java·算法·sentinel
it噩梦28 分钟前
springboot 工程使用proguard混淆
java·spring boot·后端
潜意识起点31 分钟前
Java数组:静态初始化与动态初始化详解
java·开发语言·python
竹影卿心33 分钟前
Java连接HANA数据库
java·数据库·windows
Abelard_42 分钟前
LeetCode--347.前k个高频元素(使用优先队列解决)
java·算法·leetcode
海海不掉头发1 小时前
软件工程-【软件项目管理】--期末复习题汇总
java·学习·产品运营·软件工程·团队开发·需求分析·期末复习
缘友一世1 小时前
java实现网络IO高并发编程java AIO
java·网络·python