组合总和II(回溯、去重)

news2024/11/25 14:40:20

40. 组合总和 II - 力扣(LeetCode)

题目描述

给定一个候选人编号的集合 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

题解

本题与该题组合总和(回溯)-CSDN博客的区别在于,candidates 候选集合中有重复的元素,然而解集中要求不能包含重复的组合,因此在求解时要对解集进行去重

举个例子,如下图,当candidates = [10,1,2,7,6,1,5],target=8时,显然[1,7]是一个解集,但是candidates 存在两个元素1,也就是图中指针a和指针c指向的元素,如果我们使用回溯法进行遍历,势必会出现两个解集[1,7],一个是[a,b],另一个是[b,c],但他们都是解集[1,7],这是不符合题意的。

关于去重 

首先我们对candidates 数组进行排序,得到如下序列:

其次,使用回溯法遍历排序后的candidates,如果遇到相邻相同的元素(candidates[i-1]==candidates[i]),跳过即可。

那么接下来的问题就转换成了,如何在回溯法中模拟这个过程?

为方便说明问题,我们假定candidates =[1,1,2],target=3.

如下图所示,排序后的candidates,如果遇到相邻的相同元素,则必有candidates[i-1]==candidates[i],但问题在于这种情况在同一树枝下深度的遍历和同一层的横向遍历都会发生,而我们要的去重是同一树层的去重,也就是在同一层的遍历下,遇到candidates[i-1]==candidates[i]就跳过。

为区别这两种情况,我们使用一个used辅助数组,记录每次取数的过程,也就是说,如果每次取到了一个数,就将used的对应位置置为true。

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

used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
used[i - 1] == false,说明同一树层candidates[i - 1]使用过

故满足我们要求的去重过程可表示为

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

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

为什么 used[i - 1] == false 就是同一树层呢,因为同一树层,used[i - 1] == false 才能表示,当前取的 candidates[i] 是从 candidates[i - 1] 回溯而来的。而 used[i - 1] == true,说明是进入下一层递归,去下一个数,所以是树枝上

详细题解过程参考:40. 组合总和 II - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/combination-sum-ii/solutions/857552/dai-ma-sui-xiang-lu-dai-ni-xue-tou-hui-s-ig29/

代码

class Solution {
private:
    vector<int> path;
    vector<vector<int>> res;
public:
    void backing(vector<int>& candidates,int target,int startIndex,int curSum,vector<bool>& used)
    {
        if(curSum>target) return;
        if(curSum==target)
        {
            res.push_back(path);
            return;
        }

        for(int i=startIndex;i<candidates.size() && curSum+candidates[i]<=target;i++)
        {
            if(i>0 && candidates[i-1]==candidates[i] && used[i-1]==false)
            {
                continue;
            }
            else
            {
                curSum+=candidates[i];
                used[i]=true;
                path.push_back(candidates[i]);
                backing(candidates,target,i+1,curSum,used);
                path.pop_back();
                curSum-=candidates[i];
                used[i]=false;
            }
        }
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        vector<bool> used(candidates.size(),0);
        backing(candidates,target,0,0,used);
        return res;
    }
};

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

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

相关文章

git submodule 用法

子仓库启蒙 在根目录执行&#xff1a; git submodule add gitgitee.com:liaosp/dcat-admin-basic-interface.git想要子模块指定的分支&#xff1a; git submodule add -b dev <仓库地址> <子模块路径>这样相当于在根目录上添加了 .gitmodules 信息&#xff0c;相…

SystemWeaver—电子电气系统协同研发平台

背景概述 当前电子电气系统在汽车领域应用广泛&#xff0c;其设计整合了多门工程学科&#xff0c;也因系统的复杂性、关联性日益提升&#xff0c;需要其提供面向软件、硬件、网络、电气等多领域交织而导致的复杂系统解决方案。并且随着功能安全、AUTOSAR、SOA、以太网通讯等新要…

【23真题】211题质量极高!押题卷有4道!

今天分享的是23年陕西师范大学831的信号与系统试题及解析。 本套试卷难度分析&#xff1a;22年陕西师范大学831考研真题&#xff0c;我也发布过&#xff0c;若有需要&#xff0c;戳这里自取&#xff01;本套试题难度中等&#xff0c;考察的题目道道经典&#xff0c;第三题是课…

【C++】三大特性 --- 继承的详细讲解

目录 1.继承的概念及定义 1.1 继承的概念 1.2 继承定义 1.2.1定义格式 1.2.2继承关系和访问限定符 1.2.3继承基类成员访问方式的变化 2.基类和派生类对象赋值转换 3.继承中的作用域 4.派生类的默认成员函数 5.继承与友元 6.继承与静态成员 7.复杂的菱形继承及菱形虚…

python中各式各样的字典操作

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在Python中&#xff0c;字典&#xff08;Dictionary&#xff09;是一种强大而灵活的数据结构&#xff0c;它允许你存储和检索键值对。本文将深入探讨Python中各式各样的字典操作&#xff0c;包括基本操作、高级操…

Octave安装与教程

Octave是一种编程语言&#xff0c;旨在解决线性和非线性的数值计算问题。Octave为GNU项目下的开源软件&#xff0c;早期版本为命令行交互方式&#xff0c;4.0.0版本发布基于QT编写的GUI交互界面。Octave语法与Matlab语法非常接近&#xff0c;可以很容易的将matlab程序移植到Oct…

区块链optimism主网节点搭建

文章目录 官方参考资料编译环境搭建编译Optimism Monorepo编译op-geth 执行下载数据快照生成op-geth和op-node通信密钥op-geth执行脚本 op-node执行脚本 启动日志op-gethop-node 本文是按照官方参考资料基于源码的方式成功搭建optimism主网节点。 官方参考资料 源码&#xff1…

人工智能在农业领域的创新解决方案

随着科技的发展和人工智能的应用越来越广泛&#xff0c;农业领域也逐渐受益于人工智能技术的创新解决方案。人工智能的引入不仅能够提高农业生产的效率和质量&#xff0c;还能够预测天气变化、监测农作物生长情况以及提供精确的农业管理建议。本文将就人工智能在农业领域的创新…

OTN设备,ZXONE 9700,ZXMP M721

文章目录 ZXONE 9700分组OTN产品产品特点 ZXMP M721城域边缘OTN产品产品特点 ZXONE 9700分组OTN产品 ZXONE 9700系列产品&#xff0c;支持10G/40G/100G/400G传输速率&#xff0c;可实现28.8T/14.4T/9.2T/4.4T ODUk的大容量电层交叉和10G/40G/100G/400G波长的光层交叉及分组交换…

Dropwizard-metric的使用

背景 近期在开发中用到了dropwizard-metric作为监控metric的埋点框架&#xff0c;由于是分布式的系统&#xff0c;前期曾经对比过hadoop-metric的实现和dropwizard-metric的实现&#xff0c;因为开发的项目后续会和hadoop的项目有一定的上下游关系&#xff0c;所以考虑排除掉h…

JAVA刷题之数组的总结和思路分享

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

荔枝FM语音批量下载

动机 最近想下载一下自己在蜻蜓FM上上传的音频&#xff0c;发现不支持批量下载。于是去找了一些下载器&#xff0c;万万没想到&#xff0c;该下载器只能下载前十条&#xff0c;再下要注册&#xff0c;注册费5元。尼玛&#xff0c;不能忍。本来就不是太难的技术&#xff0c;还搞…

HarmonyOS应用开发——页面

我们将对于多页面以及更多有趣的功能展开叙述&#xff0c;这次我们对于 HarmonyOS 的很多有趣常用组件并引出一些其他概念以及解决方案、页面跳转传值、生命周期、启动模式&#xff08;UiAbility&#xff09;&#xff0c;样式的书写、状态管理以及动画等方面进行探讨 页面之间…

探索Python的神奇力量:详解setattr函数的使用教程

概要&#xff1a; 在Python这个强大而灵活的编程语言中&#xff0c;有许多函数可以帮助开发者实现各种各样的任务。其中一个非常有用且功能强大的函数是setattr函数。setattr函数允许我们在运行时动态地设置对象的属性值&#xff0c;这为我们的代码增加了灵活性和扩展性。本文…

mvc模式test

项目结构 Book.java package beans; public class Book {private Integer id;private String name;private double price;public Integer getId() {return id;}public void setId(Integer id) {this.id id;}public String getName() {return name;}public void setName(Strin…

申请SSL证书的步骤

一&#xff1a;首先确定自己所需要的证书类型 1&#xff1a;小微企业以及个人网站选择免费的DV证书是完全够用的。 2&#xff1a;中大型企业尤其是涉及到需要用户填写账户密码的建议OV及以上的证书。 3&#xff1a;根据适配范围确认需要的是单域名&#xff0c;多域名&#xff0…

python安装与配置:在centos上使用shell脚本一键安装

介绍 Python是一种功能强大且广泛使用的编程语言&#xff0c;但在某些情况下&#xff0c;您可能需要安装和配置特定版本的Python。本教程将向您展示如何使用一个Shell脚本自动完成这个过程&#xff0c;以便您可以快速开始使用Python 3。 使用shell自动化安装教程 1. 复制脚本…

java:spring-boot-starter-actuator的使用

简介 Spring Boot Actuator 是 Spring Boot 提供的一个功能强大的模块&#xff0c;用于监控和管理您的应用程序。它为开发人员和运维团队提供了许多有用的端点&#xff0c;用于获取有关应用程序运行时状态的信息。 什么是端点&#xff1f; "端点"是指提供了某种功能…

C++作业6

以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴子等。现在&#xff0c;动物园里有一位讲解员&…

关于对Spring事件监听机制相关解析

1、Spring事件监听器使用 Spring事件监听体系包括三个组件&#xff1a;事件、事件监听器&#xff0c;事件广播器 事件&#xff1a;定义事件类型和事件源&#xff0c;需要继承ApplicationEvent import org.springframework.context.ApplicationEvent; public class OrderEvent…