Leetcode 剑指 Offer II 081.组合总和

news2024/11/28 1:53:40

题目难度: 中等

原题链接

今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~

题目描述

给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。

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

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

示例 1:

  • 输入: candidates = [2,3,6,7], target = 7
  • 输出: [[7],[2,2,3]]

示例 2:

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

示例 3:

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

示例 4:

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

示例 5:

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

提示:

  • 1 <= candidates.length <= 30
  • 1 <= candidates[i] <= 200
  • candidate 中的每个元素都是独一无二的。
  • 1 <= target <= 500

题目思考

  1. 如果限制只能用递归或者迭代, 如何解决?

解决方案

方案 1

思路
  • 首先我们可以尝试用递归的思路来解决
  • 分析题目, 我们可以发现针对 candidates 的每个数字, 都可以细分成两种情况: (1) 将该数字添加到组合中, 继续处理当前数字; (2) 不再添加当前数字, 开始处理下一个数字
  • 我们可以基于上述分析进行递归求解, 具体做法如下:
    • 传入当前下标, 当前组合, 以及当前组合的数字之和
    • 如果当前数字和恰好等于 target, 则将当前组合加入最终结果, 并返回
    • 如果当前数字和已经大于 target, 或者当前下标超出数组范围, 则没必要继续递归了, 直接返回
    • 如果不是上述两种情况, 则说明可以继续递归: 此时要么继续使用当前数字, 将其添加到当前组合中, 同时保持当前下标不变; 要么不再使用当前数字, 当前组合保持不变, 同时将当前下标加 1
  • 由于每条递归路径添加的数字个数都不一样, 所以每个递归出口形成的有效组合也各不相同, 无需手动去重
复杂度
  • 时间复杂度 O(2^M): 假设 sum(ceil(target/candidate))是 M (candidate 是 candidates 中的每个数字), 意味着最多进行 M 次判断, 每次判断都有两种可能性, 所以总时间是 2^M
  • 空间复杂度 O(M): 递归栈的消耗, 最差情况下长度是 M
代码
Python 3
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        # 方法1: 两分支递归
        n = len(candidates)
        res = []

        # 递归传入当前下标, 当前组合以及当前组合的数字之和
        def dfs(i, path, sm):
            if sm == target:
                # 递归出口#1, 找到一个有效组合, 将其加入最终结果集
                res.append(path)
                return
            if i >= n or sm > target:
                # 递归出口#2, 当前组合已经不可能满足要求了, 直接返回
                return
            # 情况1: 将该数字添加到组合中, 继续处理当前数字
            dfs(i, path + [candidates[i]], sm + candidates[i])
            # 情况2: 不再添加当前数字, 开始处理下一个数字
            dfs(i + 1, path, sm)

        dfs(0, [], 0)
        return res

方案 2

思路
  • 接下来我们尝试用迭代的思路来解决
  • 我们可以将递归函数的三个参数作为一个三元组存储起来
  • 然后遍历这个三元组列表, 同样利用递归方案的分析来进行相应处理
  • 只是需要将递归出口的 return 改成 continue, 以及将递归调用改成追加新的三元组到列表中
  • 下面代码中有详细的注释, 方便大家理解
复杂度
  • 时间复杂度 O(2^M): 分析同方案 1
  • 空间复杂度 O(2^M): 需要保存所有可能的三元组
代码
Python 3
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        # 方法2: 三元组迭代
        n = len(candidates)
        res = []
        # (当前下标,当前组合,当前组合的数字之和)
        tuples = [(0, [], 0)]
        for i, path, sm in tuples:
            if sm == target:
                # 找到一个有效组合, 将其加入最终结果集, 继续循环
                res.append(path)
                continue
            if i >= n or sm > target:
                # 当前组合已经不可能满足要求了, 不再继续处理它, 继续循环
                continue
            # 情况1: 将该数字添加到组合中, 继续处理当前数字
            tuples.append((i, path + [candidates[i]], sm + candidates[i]))
            # 情况2: 不再添加当前数字, 开始处理下一个数字
            tuples.append((i + 1, path, sm))
        return res

大家可以在下面这些地方找到我~😊

我的 GitHub

我的 Leetcode

我的 CSDN

我的知乎专栏

我的头条号

我的牛客网博客

我的公众号: 算法精选, 欢迎大家扫码关注~😊

算法精选 - 微信扫一扫关注我

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1804983.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Transformer论文精读

Transformer&#xff1a;Attention is all you need Abstract&#xff1a; 在主流的序列转录模型&#xff08;sequence transduction models&#xff1a;给一个序列&#xff0c;生成另一个序列&#xff09;&#xff0c;主要依赖循环或者卷积神经网络&#xff0c;一般是用enco…

【遗传算法】【机器学习】【Python】常见交叉方法(二)、多点交叉和均匀交叉

往期遗传算法文章见&#xff1a; 【遗传算法】【机器学习】【Python】常见交叉方法&#xff08;一&#xff09;、单点交叉和两点交叉 一、遗传算法流程图 交叉过程即存在于上图的”交叉“&#xff08;crossover&#xff09;步骤中。 二、多点交叉 多点交叉的原理就是&#x…

RISCV中CLINT和PLIC解析

中断这个东西理论上属于CPU核心的东西。一般来说并不需要重新设计。实际的实现中是比较繁琐的&#xff0c;此处只介绍原理。ARM基本上会用NVIC(Nested Vectored Interrupt Controller) 的东西&#xff0c;RISC-V目前实现了一个比较简单的东西&#xff08;有人称之为简洁高效&am…

算法 | hbut期末复习笔记

贪心选择策略&#xff1a;所求问题的整体最优解可以通过一系列局部最优的选择&#xff08;贪心选择&#xff09;得到 最优子结构&#xff1a;问题的最优解包括了其子问题的最优解 回溯法&#xff1a;具有限界函数的深度优先搜索法 回溯法的解空间&#xff1a;子集树&排列…

【计网复习】应用层总结(不含HTTP和错题重点解析)

应用层总结&#xff08;不含HTTP和错题重点解析&#xff09; 应用层简介 应用层的主要功能常见的应用层协议小林对于应用层通常的解释 网络应用模型 客户端-服务器模型&#xff08;Client-Server Model, C/S&#xff09; 特点优点缺点应用场景 对等网络模型&#xff08;Peer-to…

【QT5.14.2】编译MQTT库example的时候报No such file or directory

【QT5.14.2】编译MQTT库example的时候报No such file or directory 前几天导师让跑一下MQTT库&#xff0c;用的5.14.2版本的QT&#xff0c;于是就上网搜了一个教程&#xff1a;https://www.bilibili.com/video/BV1dH4y1e7hG/?spm_id_from333.337.search-card.all.click&v…

TCP/IP协议介绍——三次握手四次挥手

TCP/IP&#xff08;Transmission Control Protocol/Internet Protocol&#xff0c;传输控制协议/网际协议&#xff09;是指能够在多个不同网络间实现信息传输的协议簇。TCP/IP协议不仅仅指的是TCP 和IP两个协议&#xff0c;而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议…

如何在隔离环境中设置 LocalAI 以实现 GPU 驱动的文本嵌入

作者&#xff1a;来自 Elastic Valeriy Khakhutskyy 你是否想在 Elasticsearch 向量数据库之上构建 RAG 应用程序&#xff1f;你是否需要对大量数据使用语义搜索&#xff1f;你是否需要在隔离环境中本地运行&#xff1f;本文将向你展示如何操作。 Elasticsearch 提供了多种方法…

每日一题——Python实现PAT甲级1077 Kuchiguse(举一反三+思想解读+逐步优化)

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 代码点评 时间复杂度分析 空间复杂度分析 总结 我要更强 方案1&#x…

Postman 打开错误的解决方法

错误如下&#xff1a; PostMan的文件都是放在用户文件下&#xff0c;所以在Local和Roaming文件夹下查看&#xff0c;并删除所有PostMan相关文件夹。 我电脑上的路径在 C:\Users\Administrator\AppData\Local 和 C:\Users\Administrator\AppData\Roaming【Administrator为系…

APP单页分发源码下载安卓苹果自动识别apk描述文件免签自动安装

下载地址&#xff1a;APP单页分发源码下载安卓苹果自动识别apk描述文件免签自动安装

Vue学习笔记_Day02

文章目录 1&#xff0c;指令修饰符2&#xff0c;样式控制3&#xff0c;v-model进阶4&#xff0c;计算属性5&#xff0c;监视器6&#xff0c;生命周期 1&#xff0c;指令修饰符 跟在指令后面&#xff0c;具有特殊的功能。 事件修饰符&#xff1a; .enter&#xff1a;只有enter…

2024-6-9 石群电路-27

2024-6-9&#xff0c;星期日&#xff0c;12:49&#xff0c;天气&#xff1a;晴&#xff0c;心情&#xff1a;晴。Hello&#xff0c;大家&#xff0c;我回来啦&#xff0c;昨天断更了一天&#xff0c;是为什么捏&#xff0c;是因为&#xff0c;我通过毕业答辩啦&#xff01;&…

Golang | Leetcode Golang题解之第133题克隆图

题目&#xff1a; 题解&#xff1a; func cloneGraph(node *Node) *Node {if node nil {return node}visited : map[*Node]*Node{}// 将题目给定的节点添加到队列queue : []*Node{node}// 克隆第一个节点并存储到哈希表中visited[node] &Node{node.Val, []*Node{}}// 广…

SpringBoot+Vue影城管理系统(前后端分离)

技术栈 JavaSpringBootMavenMySQLMyBatisVueShiroElement-UI 角色对应功能 用户管理员 功能截图

2024050702-重学 Java 设计模式《实战状态模式》

重学 Java 设计模式&#xff1a;实战状态模式「模拟系统营销活动&#xff0c;状态流程审核发布上线场景」 一、前言 写好代码三个关键点 如果把写代码想象成家里的软装&#xff0c;你肯定会想到家里需要有一个非常不错格局最好是南北通透的&#xff0c;买回来的家具最好是品…

如何在手机上恢复误删除的视频?

说到移动设备上的视频恢复&#xff0c;我们仍将揭开4种解决方案供您使用。希望它们对您的案件有所帮助。 众所周知&#xff0c;我们移动设备上的视频应用程序将创建一个缓存文件夹&#xff0c;以在它们永远消失之前临时存储已删除的项目。因此&#xff0c;有许多iPhone / Andr…

Thermal-BST自动化工具在Flotherm建模中的应用与优势

引言 随着科技的不断发展&#xff0c;电子领域的需求也越来越广泛和多样化。然而&#xff0c;PCB板及其上的器件建模问题一直是电子工程师在设计过程中面临的重要挑战之一。软件中原有的PCB建模工具&#xff0c;转换出来的模型复杂&#xff0c;影响后期的网格划分&#xff0c;…

SpringBoot+Vue学生宿舍管理系统(前后端分离)

技术栈 JavaSpringBootMavenMySQLMyBatisVueShiroElement-UI 角色对应功能 学生宿管员管理员 功能截图

你好GPT-4o——对GPT-4o发布的思考与看法

你好GPT-4o 前言 2024年5月13日&#xff0c;OpenAI官网发布了他们的新一代自然语言处理交互系统——GPT-4o。这是OpenAI继GPT4之后又一个新的旗舰模型。 GPT-4o&#xff08;“o”代表“omni”&#xff09;是迈向更自然的人机交互的一步——它接受文本、音频、图像和视频的任意…