【陪伴式刷题】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) 层。
相关推荐
郝学胜-神的一滴几秒前
超越Spring的Summer(一): PackageScanner 类实现原理详解
java·服务器·开发语言·后端·spring·软件构建
摇滚侠2 分钟前
Java,举例说明,函数式接口,函数式接口实现类,通过匿名内部类实现函数式接口,通过 Lambda 表达式实现函数式接口,演变的过程
java·开发语言·python
打工的小王5 分钟前
java并发编程(七)ReentrantReadWriteLock
java·开发语言
lang201509285 分钟前
Java并发革命:JSR-133深度解析
java·开发语言
abluckyboy7 分钟前
基于 Java Socket 实现多人聊天室系统(附完整源码)
java·开发语言
Re.不晚11 分钟前
JAVA进阶之路——数据结构之线性表(顺序表、链表)
java·数据结构·链表
毅炼11 分钟前
Java 基础常见问题总结(3)
java·开发语言
亓才孓20 分钟前
[JDBC]事务
java·开发语言·数据库
CHU72903522 分钟前
直播商城APP前端功能全景解析:打造沉浸式互动购物新体验
java·前端·小程序
侠客行03177 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读