组合总和 II

news2024/11/20 15:38:17

1题目

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次 。

注意:解集不能包含重复的组合。 

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

示例 2:

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

提示:

  • 1 <= candidates.length <= 100
  • 1 <= candidates[i] <= 50
  • 1 <= target <= 30

2链接

题目链接:40. 组合总和 II - 力扣(LeetCode)

视频链接:回溯算法中的去重,树层去重树枝去重,你弄清楚了没?| LeetCode:40.组合总和II_哔哩哔哩_bilibili

3解题思路

本题与其他组合不一样的地方在于:

  1. 本题candidates 中的每个元素在每个组合中只能使用一次。
  2. 本题数组candidates的元素是有重复的,而39.组合总和 (opens new window)是无重复元素的数组candidates

本题的难点在于区别2中:集合(数组candidates)有重复元素,但还不能有重复的组合。把所有组合求出来,再用set或者map去重,这么做很容易超时!

所谓去重,其实就是使用过的元素不能重复选取。那么问题来了,我们是要同一树层上使用过,还是同一树枝上使用过呢?题目说,元素在同一个组合内是可以重复的,怎么重复都没事,但两个组合不能相同。所以我们要去重的是同一树层上的“使用过”,同一树枝上的都是一个组合里的元素,不用去重

举一个例子,candidates = [1, 1, 2], target = 3,(方便起见candidates已经排序了):

回溯三部曲:

1、确定参数和返回值

path和result与前面的一些题目相同,除此之外,本题还需要加一个bool型数组used,用来记录同一树枝上的元素是否使用过。这个集合去重的重任就是used来完成的。

vector<vector<int>> result; // 存放组合集合
vector<int> path;           // 符合条件的组合
void backtracking(vector<int>& candidates, int target, int sum, int startIndex, vector<bool>& used) {

2、确定终止条件

终止条件为 sum > target 和 sum == target

sum > target 这个条件其实可以省略,因为在递归单层遍历的时候,会有剪枝的操作,下面会介绍到。

if (sum > target) { // 这个条件其实可以省略
    return;
}
if (sum == target) {
    result.push_back(path);
    return;
}

3、确定单层递归逻辑

前面提到:要去重的是“同一树层上的使用过”。那么如何判断同一树层上元素(相同的元素)是否使用过了呢。

如果candidates[i] == candidates[i - 1] 并且 used[i - 1] == false,就说明:前一个树枝,使用了candidates[i - 1],也就是说同一树层使用过candidates[i - 1]

此时for循环里就应该做continue的操作。

这块比较抽象,如图:

可以看出在candidates[i] == candidates[i - 1]相同的情况下:

  • used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
  • used[i - 1] == false,说明同一树层candidates[i - 1]使用过
for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {
    // used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
    // used[i - 1] == false,说明同一树层candidates[i - 1]使用过
    // 要对同一树层使用过的元素进行跳过
    if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {
        continue;
    }
    sum += candidates[i];
    path.push_back(candidates[i]);
    used[i] = true;
    backtracking(candidates, target, sum, i + 1, used); // 和39.组合总和的区别1:这里是i+1,每个数字在每个组合中只能使用一次
    used[i] = false;
    sum -= candidates[i];
    path.pop_back();
}

注意sum + candidates[i] <= target为剪枝操作

4代码

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& candidates, int target, int sum, int startIndex, vector<bool>& used) {
        if (sum > target) return ;
        if (sum == target) {
            result.push_back(path);
            return ;
        }
        for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {
            // used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
            // used[i - 1] == false,说明同一树层candidates[i - 1]使用过
            // 要对同一树层使用过的元素进行跳过
            if (i > 0 && candidates[i] == candidates[i-1] && used[i-1] == false) {
                continue;
            }
            path.push_back(candidates[i]);
            sum += candidates[i];
            used[i] = true;
            backtracking(candidates, target, sum, i+1, used);
            path.pop_back();
            sum -= candidates[i];
            used[i] = false;
        }
    }
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<bool> used(candidates.size(), false);
        sort(candidates.begin(), candidates.end());
        backtracking(candidates, target, 0, 0, used);
        return result;
    }
};

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

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

相关文章

搭建LightPicture开源免费图床系统「公网远程控制」

文章目录 1.前言2. Lightpicture网站搭建2.1. Lightpicture下载和安装2.2. Lightpicture网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 转载自cpolar极点云的文章&#xff1a;【搭建私人图床】使用LightPicture开源…

Parasoft亮相上海国际嵌入式展

全球自动化软件测试解决方案的领导者Parasoft宣布参加6月14日至16日在上海举行的首届embedded world China上海国际嵌入式展&#xff0c;此次Parasoft联合检测认证领域的领导者-莱茵技术&#xff08;上海&#xff09;有限公司共同参展&#xff0c;为嵌入式行业提供符合功能安全…

电子表格的武侠江湖里,有VBA加持的Excel,也只能算一把菜刀

Excel&#xff0c;都用过吧&#xff1f; 没用过肯定也听说过。 这可是Windows里颇具传奇色彩的软件&#xff0c;堪称一把九天陨铁淬炼而成的菜刀。 普通人&#xff0c;用它做表格&#xff0c; 进行简单的数据汇总。 职场人&#xff0c;继续用它做表格&#xff0c; 开始求和…

请问下大家PMP证书值得考嘛?

做项目的去考&#xff0c;项目经理、产品经理这些&#xff0c;或者有往项目管理领域发展的去考。其他行业有空可以学习下 不一定要考证了。 PMP证书更多的是 “敲门砖”作用&#xff0c;大部分公司招聘的门槛都要去了这个证书。 当然现在PMP管理模式也很热门&#xff0c;各大…

国产的高精度ADC HX711 CS1237 TM7707等如何选型

最近小伙伴们咨询我&#xff0c;国产很多高精度的ADC&#xff0c;如何选型使用呢&#xff1f;这里我们主要讨论几款24位差分输入。 ADC/DAC相关名词解释 ADC输入范围ADC转换速度ADC稳定位数 在我们选的时候主要考虑上面三个参数 ADC参数对比 型号输入范围输出速率建立时间PG…

网页JS自动化脚本(八)使用网页专属数据库indexedDB进行数据收集

我们在网页上进行的活动,往往都需要进行收集一些简单的数据,但是因为浏览器的安全原因,浏览器基本上是无法与本地的操作系统直接产生数据交互的,这本来就是一个由于安全问题生产的无解问题,在浏览器里面是内置了几种数据库的,其中一种就是indexedDB,可以用来储存一些非常小的数…

多主题插件上线!开源的 API 管理工具居然这么有意思!

之前我一直在用的开源API 管理工具——Postcat 最近上线了新的主题插件&#xff0c;真的有意思&#xff01; 之前就用用户提 issue 没想到终于安排上了&#xff0c;给这个项目点赞&#xff01; 挑几款我偏好的主题插件&#xff0c;简单看看 第一款&#xff0c;【VSCode 主题】&…

鸿蒙Hi3861学习二十-编译构造

一、简介 在使用编译构造子系统前&#xff0c;应了解如下基本概念&#xff1a; 子系统 子系统是一个逻辑概念&#xff0c;它由一个或多个具体的组件构成、OpenHarmony整体遵从分层设计&#xff0c;从下向上依次为&#xff1a;内核层、系统服务层、架构层和应用层。系统功能按照…

电商用户行为分析__求前3点击量

测试代码 package Data_textimport org.apache.flink.streaming.api.TimeCharacteristic import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor import org.apache.flink.streaming.api.scala._ import org.apache.flink.st…

KWin事件总结和相关类介绍

KWin事件总结和相关类介绍 目录 KWin事件总结和相关类介绍 1、事件相关模块 1.1 事件类型 1.2 事件管理 1.3 事件过滤器 2、KWin其他模块整理 2.1 窗口 2.2 Item 2.3 scene 3、事件传递流程 3.1 事件整体流程 3.2 事件传递时序图 4、事件流程样例 4.1 鼠标拖动修…

英伟达发布 532.03 驱动,为新游戏和新显卡带来支持

继英伟达 RTX 4060系列显卡陆续发售后&#xff0c;又发布了 GeForce Game Ready 532.03 WHQL 驱动&#xff0c;驱动人生整理了一下NVIDIA GeForce Game Ready 532.03 WHQL 驱动带来的支持与优化。 GeForce Game Ready 532.03 WHQL 驱动主要同步支持 RTX 4060 Ti 8G 显卡&#…

Hadoop3.1.4分布式搭建

Hadoop3.1.4分布式搭建 1. 基础环境准备 1.1 实验网络规划 hostnameip addrroleotherk8s-m13310.10.10.133NameNode, DataNode, NodeManageerk8s-m13410.10.10.134SecondaryNameNode, DataNode, NodeManageerk8s-m13510.10.10.135ResourceManager, DataNode, NodeManageerk8…

Java 多线程基础

文章目录 Java 多线程基础一、相关概念1. 程序、进程和线程2. 线程调度3. 并行与并发 二、线程的创建1. 继承 Thread 类2. 实现 Runnable 接口3. 实现 Callable 接口4. 线程池 三、Thread 类常用方法1. 构造方法2. 常用方法3. 其他方法 四、线程的生命周期五、线程同步1. 线程安…

Serverless 是什么?

文章目录 Serverless 是什么&#xff1f;Serverless 的前世今生面临挑战以应用为中心&#xff0c;无需运营基础架构自动伸缩为价值付费内置高可用和高安全 Serverless 行业及应用场景IT 自动化数据处理微服务架构IoT 后端系统游戏 Serverless 解决方案推荐SaaS Boot适合客户方案…

代码审查 idea

目录 文档 alibaba java coding guidelines 插件下载 Upsource 文档 https://download.csdn.net/download/qq_41169544/87545171https://download.csdn.net/download/qq_41169544/87545171 alibaba java coding guidelines 插件下载 Alibaba Java Coding Guidelines安装使用…

【珍藏版】SolVES模型的生态系统服务功能社会价值评估及拓展

生态系统服务是人类从自然界中获得的直接或间接惠益&#xff0c;可分为供给服务、文化服务、调节服务和支持服务4类&#xff0c;对提升人类福祉具有重大意义&#xff0c;且被视为连接社会与生态系统的桥梁。自从启动千年生态系统评估项目&#xff08;Millennium Ecosystem Asse…

OSI(Open System Interconnect)开放系统互联参考模型-7层模型(改版)

OSI&#xff08;Open System Interconnect&#xff09;开放系统互联参考模型-7层模型 1. OSI七层模型1.1 基本概念1.2 七层模型的划分1.3 数据传输过程 2. TCP/IP四层模型2.1 基本概念2.2 四层模型的划分2.3 数据传输过程 3. 涉及的协议及概念3.1 MTU1. 概念2. 关于mtu取值3. 修…

Anchor Free目标检测方法

faster rcnn anchor&#xff1a;尺寸比例固定 yolo anchor尺寸确定&#xff1a;通过聚类 Anchor Free方法 anchor的简单理解&#xff1a;在特征图上的模板&#xff0c;含有的信息为检测框的大小和尺度 Anchor based 方法小结 Faster rcnn(左上) yolo v3(右上) ssd (中) re…

python爬虫学习简记(更新中)

页面结构的简单认识 如图是我们在pycharm中创建一个HEML文件后所看到的内容 这里我们需要认识的是上图的代码结构&#xff0c;即html标签包含了head标签与body标签 table标签 table标签代表了一个网页页面中的表格&#xff0c;其包含了行和列&#xff0c;其中行标签我们使用tr标…

1.场景设计题

系统设计 文章目录 系统设计一、缓存设计1、Redis 缓存Key回收策略&#xff1f;1.1、Redis缓存Key过期策略1.2、Redis缓存Key回收策略 2、Redis缓存击穿如何解决&#xff1f;2.1、导致Redis缓存穿透原因有那些&#xff1f; 3、Redis缓存雪崩如何解决&#xff1f;4、Redis缓存击…