【回溯算法题记录】组合总和题汇总

news2024/11/24 14:24:10

组合总和

  • 39. 组合总和
    • 题目描述
    • 初始思路
    • 后续分析
  • 40. 组合总和 II
    • 题目描述
    • 思路(参考代码随想录)

39. 组合总和

题目🔗

题目描述

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

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

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

初始思路

好久没有做回溯的题了,首先画图分析一下:
在这里插入图片描述
因为这题可以重复选取,那么我们每次选取都是在一个相同的集合中(例如candidates={2, 3, 6, 7})。所以除了第一次选择的元素之外,我们之后所做的操作都是相同的,那么就可以定义一个cur_idx来表示我们首次选择的元素的index,用一个一维数组vec来记录当前路径,当vec中的和等于target时,就把这条路径放入最终结果集result中。于是我开始写的代码就是这样的:

class Solution {
public:
    void backtracking(int cur_idx, int target, vector<int>& candidates, vector<int>& vec, vector<vector<int>>& results){
        // 终止条件
        if(accumulate(vec.begin(), vec.end(), 0)==target){
            if(find(results.begin(), results.end(), vec)==results.end()) results.push_back(vec);
            return;
        }

        for(int i = 0; i < candidates.size(); i++){
            if(accumulate(vec.begin(), vec.end(), 0)+candidates[i]<=target)
                vec.push_back(candidates[i]);
            backtracking(i+1, target, candidates, vec, results);
            vec.pop_back();
        }  

    }

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<int> vec;
        vector<vector<int>> results;
        backtracking(0, target, candidates, vec, results);
        return results;
    }
};

但是不出意料的没通过。。

后续分析

还是认真地走一下三部曲吧QAQ

  1. 递归函数参数
    和我上面分析的一样:
vector<int>& vec;
vector<vector<int>>& results;
void backtracking(int cur_idx, int sum, int target, vector<int>& candidates);

vecresults放在类成员变量中,就不用写在函数入口。sum是当前路径统计的和。

  1. 递归终止条件
    在这里插入图片描述
    从上图来看,当前路径vec的总和sum大于等于target时,就要返回,并且当sum==target时,我们就要收集结果。
if(sum > target) return;
if(sum == target) {
	result.push_back(vec);
	return;
}

啊,可以看出我刚开始忽略了sum>target的情况。

  1. 单层搜索逻辑
    这层的重点在于重复选取的实现,先看代码:
for (int i = cur_idx; i < candidates.size(); i++) {
    sum += candidates[i];
    path.push_back(candidates[i]);
    backtracking(candidates, target, sum, i); // 关键点:不用i+1了,表示可以重复读取当前的数
    sum -= candidates[i];   // 回溯
    path.pop_back();        // 回溯
}

在这里插入图片描述
整体的逻辑就是我上面这张图这样(第二行的{2, 3} sum=5后面应该还有哈,但是我懒得画了)。

所以整体代码是:

class Solution {
public:
    vector<int> vec;
    vector<vector<int>> results;
    void backtracking(int cur_idx, int sum, int target, vector<int>& candidates){
        // 终止条件
        if(sum == target){
            results.push_back(vec);
            return;
        }
        if(sum > target) return;

        // 单层逻辑
        for(int i = cur_idx; i < candidates.size(); i++){
            vec.push_back(candidates[i]);
            sum += candidates[i];
            backtracking(i, sum, target, candidates);
            sum -= candidates[i];
            vec.pop_back();
        }  

    }

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vec.clear();
        results.clear();
        backtracking(0, 0, target, candidates);
        return results;
    }
};

40. 组合总和 II

题目🔗

题目描述

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

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

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

思路(参考代码随想录)

这题的难点在于集合中有重复元素,但是结果中不能包含重复的组合

这里我们要明白重复有两种情况:树枝重复和树层重复。
在这里插入图片描述
借用卡哥的图来说明一下。树枝重复是左边的情况,树层重复是中间的情况。而这题不能出现的是树层重复。这里我们用一个used数组来表示每一个数是否被使用。

从上面这个图可以看出,当我们在树的第二层(集合已经被排序过了,相同元素挨在一起),当我们取第二个1的时候,也就是candicates[1],而前面的candidates[0]也是1,说明已经重复读取了,所以我们判断在同一树层是否重复读取的逻辑是i > 0 && candidates[i] == candidates[i-1] && used[i-1] == 0

整体代码如下

class Solution {
public:
    vector<int> path;
    vector<vector<int>> results;

    void backtracking(int index, int target, vector<int>& candidates, int sum, vector<int>& used) {
        if(sum == target) {
            results.push_back(path);
            return;
        }
        if(sum > target) {
            return;
        }

        for(int i = index; i < candidates.size(); i++) {
            if(i > 0 && candidates[i] == candidates[i-1] && used[i-1] == 0)
                continue;
            sum += candidates[i];
            path.push_back(candidates[i]);
            used[i] = 1;
            backtracking(i+1, target, candidates, sum, used);
            sum -= candidates[i];
            path.pop_back();
            used[i] = 0;
        }
    }

    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<int> used(candidates.size(), 0);
        sort(candidates.begin(), candidates.end());
        path.clear();
        results.clear();
        int sum = 0;
        backtracking(0, target, candidates, sum, used);
        return results;
    }
};

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

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

相关文章

开源网安参与编制的《代码大模型安全风险防范能力要求及评估方法》正式发布

​代码大模型在代码生成、代码翻译、代码补全、错误定位与修复、自动化测试等方面为研发人员带来了极大便利的同时&#xff0c;也带来了对安全风险防范能力的挑战。基于此&#xff0c;中国信通院依托中国人工智能产业发展联盟&#xff08;AIIA&#xff09;&#xff0c;联合开源…

教你使用 Go 语言访问智谱 AI 大模型!

AI 大模型太火爆了&#xff01;我在工作中经常使用它们&#xff0c;感觉已经离不开了&#xff01; 最近测试了智谱 AI 大模型&#xff0c;实测下来感觉还挺不错的。 官方提供了体验包&#xff0c;注册并实名认证之后有 300 万 token&#xff0c;非常壕&#xff01; 今天的股…

uni-push(2.0)常见问题,Android平台

将常用的网址一定要收藏在标签栏中&#xff0c;方便后期找&#xff0c;不然后期会很生气。 草料二维码&#xff0c;这个在线工具可以将打包生成的apk文件生成二维码&#xff0c;供测试人员测试。生成的apk只有五次下载机会&#xff0c;可点击链接后的一键上传&#xff0c;这样…

站在巨人的肩膀上 C语言理解和简单练习(包含指针前的简单内容)

1.格式化的输入/输出 1.1printf函数 printf函数你需要了解的就是转换说明&#xff0c;转换说明的作用是将内存中的二进制转换成你所需要的格式入%d就是将内存中存储的变量的二进制转化为十进制并打印出来&#xff0c;同时我们可以在%X的转换说明对精度和最小字段宽度的指定&a…

如何在SpringBoot中自定义starter

如何在SpringBoot中自定义starter Spring Boot 提供了一种简便的方法来创建自定义的 starter&#xff0c;从而帮助开发者封装常用的配置和依赖。本文将介绍如何在 Spring Boot 中自定义一个 starter。 1. 创建 Maven 项目 首先&#xff0c;创建一个新的 Maven 项目&#xff…

SpringBoot开启事务日志

一般框架开启日志的方式&#xff1a; 开启某个包下的日志就写该包路径&#xff0c;开启某个类下的日志就写该类路径。

全国首场以AI数字内容风控为主题的大会,开放参会报名中

网易易盾将于2024年7月6日举办一场AI数字内容风控大会&#xff0c;邀请AI产业链的基础层、模型层和应用层的企业代表&#xff0c;科研机构、律所、院校的专家老师&#xff0c;探讨大模型时代下的自由与责任等话题。参会报名链接&#xff1a;https://sourl.cn/vqUU7X&#xff0c…

【计算机毕业设计】基于Springboot的月度员工绩效考核管理系统【源码+lw+部署文档】

包含论文源码的压缩包较大&#xff0c;请私信或者加我的绿色小软件获取 免责声明&#xff1a;资料部分来源于合法的互联网渠道收集和整理&#xff0c;部分自己学习积累成果&#xff0c;供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者…

HTTP/2 头部压缩 Header Compress(HPACK)详解

文章目录 1. HPACK 的工作原理1.1 静态表1.2 动态表 2. 压缩过程2.1 编码过程2.2 解码过程 3. HPACK 的优势 在HTTP1.0中&#xff0c;我们使用文本的形式传输header&#xff0c;在header中携带cookie的话&#xff0c;每次都需要重复传输几百到几千的字节&#xff0c;这着实是一…

推荐系统-FM模型

参考&#xff1a;推荐系统&#xff08;三&#xff09;Factorization Machines&#xff08;FM&#xff09;_svmmf-CSDN博客 一句话概括下FM&#xff1a;隐式向量特征交叉----类似embedding的思想 LR 如果利用LR做特征的二阶交叉&#xff0c;有&#xff1a; 但这个公式存在显著…

从0开始C++(七):继承

相关文章&#xff1a; 从0开始C&#xff08;一&#xff09;&#xff1a;从C到C 从0开始C&#xff08;二&#xff09;&#xff1a;类、对象、封装 从0开始C&#xff08;三&#xff09;&#xff1a;构造函数与析构函数详解 从0开始C&#xff08;四&#xff09;&#xff1a;作…

香港服务器托管对外贸行业必要性和优势

在当今全球化的经济环境下&#xff0c;外贸企业面临着前所未有的机遇与挑战。其中&#xff0c;服务器托管的选择对于外贸企业的运营效率和市场拓展具有举足轻重的作用。香港服务器&#xff0c;凭借其独特的地理位置、优质的网络环境和卓越的服务性能&#xff0c;一直是外贸企业…

2024年必备的15个免费 SVG 设计资源

在动态设计领域&#xff0c;SVG&#xff08;可缩放矢量图形&#xff09;已成为设计师打造响应迅速、清晰且适应性强的视觉效果的必备工具。 这些设计非常适合幻灯片 PowerPoint 演示文稿、应用程序设计、网站设计、原型设计、社交媒体帖子等。 在这篇文章中&#xff0c;我们将…

这份AI绘画攻略赶紧码住!超适合小白入门的PS AI插件来啦!

有没有小伙伴对AI绘画很感兴趣&#xff0c;但是看到国外的mj和sd总觉得入门困难&#xff01;别担心&#xff0c;米兔挖到一款超级绝的国产PS AI插件&#xff01;适合新手学习&#xff0c;米兔这里还有一份专为小白准备的AI绘画攻略&#xff0c;让你的创意不再受限&#xff01; …

评测|贪吃小猫疯狂长肉,让它停不下嘴的希喂、鲜朗、帕特真实调研

我发现很多铲屎官存在一个误区&#xff0c;认为“进口即是高贵”&#xff0c;过度信赖进口产品。一见到进口宠物粮就冲动购买&#xff0c;甚至对国产品牌持贬低态度&#xff0c;贴上“质量不佳”、“不符合标准”等标签。 为了更深入地了解这一现象&#xff0c;我深入研究了主食…

minio+tusd+uppy搭建文件上传服务

1、docker部署minio、tusd服务 1.1 新建docker-compose.yml minio API: http://ip:9100 minio控制台: http://ip:9101 tus API: http://ip:9102/files/ tus webhooh: http:172.0.0.1:3000/files/webhooh(用户鉴权API) version: 3.7services:minio:image: minio/minio:RELEAS…

工业软件的分类与选择策略:针对中小企业的实际应用考量

工业软件是现代工业体系的“大脑”&#xff0c;已经渗透到几乎所有工业领域的核心环节&#xff0c;是现代产业之“魂”&#xff0c;是制造强国之重器。工业软件通过优化生产流程、实时监控设备状态、实现自动化控制等功能&#xff0c;可以帮助企业显著提升生产效率和质量&#…

python爬虫-爬虫的基础知识储备

爬虫就是一个不断的去抓去网页的程序&#xff0c;根据我们的需要得到我们想要的结果&#xff01;但我们又要让服务器感觉是我们人在通过浏览器浏览不是程序所为&#xff01;归根到底就是我们通过程序访问网站得到html代码&#xff0c;然后分析html代码获取有效内容的过程。下面…

透明屏幕的魅力:为何它如此受欢迎

在科技日新月异的今天&#xff0c;透明屏幕技术以其独特的魅力和广泛的应用前景&#xff0c;逐渐成为了科技领域的一颗璀璨明星。从智能手机、平板电脑到大型显示屏&#xff0c;透明屏幕技术以其前所未有的视觉体验和实用性&#xff0c;赢得了广大消费者的喜爱。 一、透明屏幕的…

苏宁易购通用卡怎么使用?

现在还有人用苏宁的礼品卡吗 前两天618&#xff0c;想买点家电&#xff0c;但是在苏宁上看价格还不如京东淘宝优惠 最后手里的苏宁卡也没用出去 本来想着要不送人算了&#xff0c;但是收卡云的价格也还不错&#xff0c;最后就卖出去了 500块钱的苏宁卡买了475&#xff0c;到…