04. 组合总和

news2025/1/13 2:59:56

1.题目链接:

39. 组合总和

2.解题思路:

2.1.题目要求:

给定一个“无重复数组candidates”和一个“目标和target” ,要求在给定 数组candidates 的范围内,输出和等于 目标和target 的组合,此组合元素可重复。

示例 1: 输入:candidates = [2,3,6,7], target = 7, 所求解集为: [ [7], [2,2,3] ]

2.2.思路:

模拟成一个n叉树,终止条件 变成 搜索的和等于目标和

 

2.3.回溯三部曲:

2.3.1.确定回溯函数参数

定义两个全局变量,一个 一维数组path 暂时存储搜集的结果,一个 二维数组result 存储最终结果集

参数除了默认的 数组candidates 和 目标和target ,还有用于记录搜集递归过程值的sum,还有一个startIndex?感觉用不上这玩意,待会试试看

vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {

 

2.3.2.确定终止条件

当 搜集数字的总和sum 等于 目标和target 的时候,可以记录并返回了

同时因为没有层数要求,会不断递归寻找合适的值,所以需要一个条件来限制层数,也就是当总和sum已经大于目标和target的时候。

if (sum > target) return;

if (sum == target) {
      result.push_back(path);
      return;
}

 

2.3.3.确定单层遍历逻辑

这里递归到下一层搜索不用像之前那样+1,因为题目说,组合可以重复。

for (int i = startIndex; 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.4.总代码:

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
        if (sum > target) {
            return;
        }
        if (sum == target) {
            result.push_back(path);
            return;
        }

        for (int i = startIndex; 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();
        }
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        result.clear();
        path.clear();
        backtracking(candidates, target, 0, 0);
        return result;
    }
};

 

2.5.剪枝优化

 如图所示,当sum > target的时候就会返回,如果可以提前预测下一层的sum 会不会大于 target,如果大于就跳过,这样就可以省去一层遍历了,剪枝成功。

剪枝可以在for循环范围作改动,在范围那提前预测,加上  && sum + candidates[i] <= target ,在预测下一层sum不大于target的前提继续递归。

注意,剪枝前记得,要先排序,不排序 sum + candidates[i] <= target的代码预测可能不准,因为,如果一开始下一层就遇见很大的数的话(超过target),那这一整层都会被剪掉,这样就缺少了很多组合。

 for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++)

 

剪枝代码如下:

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
        if (sum == target) {
            result.push_back(path);
            return;
        }

        // 如果 sum + candidates[i] > target 就终止遍历
        for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {
            sum += candidates[i];
            path.push_back(candidates[i]);
            backtracking(candidates, target, sum, i);
            sum -= candidates[i];
            path.pop_back();

        }
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        result.clear();
        path.clear();
        sort(candidates.begin(), candidates.end()); // 需要排序
        backtracking(candidates, target, 0, 0);
        return result;
    }
};

 

3.遇见的问题:

3.1starIndex的作用?

写了一遍,一开始感觉是固定每一层递归从0开始。

但下一层递归传的不是starIndex,是 i ?。这是什么原理?

按理来说反正下一层递归 i 默认都是被index赋值等于 0 的,也就是传入啥都可以,不影响

但是这样却报错了,要换成 i 才给过,回忆下过程每一层都是从 0 开始,传入的 i 在我看来根本没意义啊,他起到的作用是什么 ?

哦哦,回看了下之前的 001.组合的代码,那里是 i+1,代表每一次取过的数不再取,哪里的index是用来定位的,

用这里的i类比的话,意思大概就是可以取,取过的数,递归下一层从 i 而不是从0开始,是因为之前的数已经取过了的意思吧

 比如画圈这里,2,5已经用过,只能从3取,哦哦,下一层递归的目的是为了避免组合重复出现,第一层已经确认大部分的组合了,后面只是补漏,从 i 取可以避免元素重复。

4.记录:

果然之前的理解还是有很多漏洞,现在补上了(大概..)

与之前题目的不同点:

  • 组合没有数量要求
  • 元素可无限重复选取

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

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

相关文章

Java程序员:三个月刷完1000道面试真题,没想到老板直接给我升职了

同事&#xff1a;前阵子听说你要跳槽&#xff0c;现在准备得怎么样啊&#xff1f;程序员T&#xff1a;不跳了同事&#xff1a;啊&#xff1f;为什么&#xff1f;程序员T&#xff1a;涨薪了呗&#xff1f;同事&#xff1a;真的吗&#xff1f;涨了多少&#xff1f;你自己跟老板谈…

卓豪再签洛钼集团,实现AD域自动化管理有效降低管理人员工作负荷

2022年11月&#xff0c;ManageEngine卓豪续签上海董禾商贸有限公司&#xff0c;将为“洛钼集团”部署ADManager Plus软件&#xff0c;助力IT管理摆脱复杂AD域管理操作&#xff0c;实现AD域管理自动化。 上海董禾商贸 上海董禾商贸有限公司作为洛钼集团在上海的主体公司。洛阳栾…

2.9.39:Flexmonster:网络报告数据透视表组件

用于网络报告的数据透视表组件 用于可视化业务数据的最强大的 JavaScript 工具 与任何技术堆栈集成 该组件可与任何技术堆栈无缝协作&#xff1a; 与Angular、React、jQuery、Vue等 完美集成 没有服务器端依赖 只需几行代码即可开始使用。 加载海量数据集 即使有超过一百万行…

珠宝商城小程序开发的价值和优势

珠宝行业的巨大利润空间就决定了行业内激烈的竞争压力&#xff0c;而随着时代的发展&#xff0c;单一的线下门店营销方式很难让珠宝行业得到更好的发展。为了防止顾客流失&#xff0c;挖掘潜在的消费潜力&#xff0c;珠宝行业开始向科技化、互联网化、移动化的方向开拓市场&…

Sentinel-2(哨兵2数据介绍)

哥白尼 Sentinel-2&#xff08;哨兵 2&#xff09;计划是一个由两颗相同的 Sentinel-2 极轨卫星组成的星座&#xff0c;两颗卫星相位差 180&#xff0c;运行在平均高度 786 km 的太阳同步轨道上。每颗卫星在其轨道上的位置由双频全球导航卫星系统&#xff08;GNSS&#xff09;接…

Kubernetes资源调度之污点与Pod容忍度

Kubernetes资源调度之污点与Pod容忍度 概述 污点是定义在节点之上的键值型属性数据&#xff0c;用于让节点有能力主动拒绝调度器将Pod调度运行到节点上&#xff0c;除非该Pod对象具有接纳节点污点的容忍度。容忍度(tolerations)则是定义在Pod对象上的键值型属性数据&#xff0c…

WAVE SUMMIT+2022明日开场,六大看点不容错过!

在2022年最后一个乐章奏响之前&#xff0c;WAVE SUMMIT第八届峰会将率先拉开帷幕。11月30日&#xff0c;由深度学习技术及应用国家工程研究中心主办、百度飞桨承办的WAVE SUMMIT2022深度学习开发者峰会将以网上直播的方式呈现。明日14点&#xff0c;冬日AI盛会WAVE SUMMIT2022将…

.Net 7 Native AOT 单文件 无依赖 跨平台

2022.11.18 Native AOT 正式发布&#xff0c;不再是 实验性项目。 .Net 7 Console App & WebApi 使用PublishAOT true&#xff0c;直接编译 成exe&#xff0c;无rutime依赖&#xff0c;智能裁剪&#xff0c;体积小&#xff0c;启动快。 环境&#xff1a; 1.更新VS2022 …

安科瑞智能余压监控系统余压控制器ARPM-C 监控余压值/接收报警信息

1、概述 ARPM-C型余压控制器&#xff0c;可监控所连接余压探测器的余压值&#xff0c;接收余压探测器的报警信息&#xff0c;并向余压监控器反馈现场工作状态&#xff0c;当余压过高报警时联动风阀执行器调节泄压阀&#xff0c;能够持续调节泄压阀的开启角度。 2、产品型号 …

Java JUC并发容器之BlockingQueue的多种实现详解

Java JUC并发容器之BlockingQueue的多种实现详解 文章目录Java JUC并发容器之BlockingQueue的多种实现详解BlockingQueueArrayBlockingQueueLinkedBlockingQueueLinkedBlockingQueue和ArrayBlockingQueue的差异PriorityBlockingQueueDelayQueueSynchronousQueueBlockingQueue …

首次公开,GitHub点击破百万的分布式高可用算法小册被我扒下来了

想成为分布式高手&#xff1f;那就先把协议和算法烂熟于心吧&#xff01;这就不得不提到著名的——《分布式高可用算法》&#xff01; 目前网上还没有开源版本&#xff0c;今天我就当一次“互联网雷锋” &#xff0c;免费获取方式我放在文末了 作者介绍 江峰&#xff0c;教授…

用R对Twitter用户的编程语言语义分析

Twitter是一个流行的社交网络&#xff0c;这里有大量的数据等着我们分析。Twitter R包是对twitter数据进行文本挖掘的好工具。最近我们被客户要求撰写关于Twitter的研究报告&#xff0c;包括一些图形和统计输出。本文是关于如何使用Twitter R包获取twitter数据并将其导入R&…

linux /usr/lib/共享库为何几乎都有链接(像是快捷方式)?

linux 共享库为什么要建立那么多link QT建立的共享库&#xff0c;输出的时候会有三个链接文件&#xff0c;有疑惑为什么要这么多文件呢&#xff1f;是什么规则考虑的&#xff1f; 可能这么做有好处&#xff0c;就是可以随时切换库的版本吧。 Linux下软链接的使用技巧 - 腾讯云…

Nodejs -- Express的安装和定义get、post方法

文章目录Express的基本使用1 安装2 基本使用3 监听GET请求4 监听POST请求5 把内容响应给客户端6 获取URL中携带的查询参数7 获取URL中的动态参数Express的基本使用 1 安装 在项目所处的目录中&#xff0c;运行如下的终端命令&#xff0c;即可将express安装到项目中使用&#…

【问题思考】二重积分积分限上的x和积分内部的x有什么区别?【几何直观】

问题 在做这个积分的时候&#xff0c;产生了一个疑问&#xff0c;就是这个积分中&#xff0c;第一次积分能将x视为常数已经成为一个下意识的动作了&#xff0c;然而&#xff0c;是否能够真的将积分中的x看作常数&#xff1f;而这个积分限上也有一个x&#xff0c;这个积分限上的…

【java|golang】1758. 生成交替二进制字符串的最少操作数

给你一个仅由字符 ‘0’ 和 ‘1’ 组成的字符串 s 。一步操作中&#xff0c;你可以将任一 ‘0’ 变成 ‘1’ &#xff0c;或者将 ‘1’ 变成 ‘0’ 。 交替字符串 定义为&#xff1a;如果字符串中不存在相邻两个字符相等的情况&#xff0c;那么该字符串就是交替字符串。例如&a…

云边缘网关TG453

5G云边缘网关TG453&#xff0c;广泛应用于工控物联网等场景&#xff0c;具备组网、数据采集、协议解析、无线通信、远程控制能力。全网通5G网络&#xff0c;同时支持边缘计算&#xff0c;满足大接入量数据处理和及时反馈的低延时任务应用。 5G云边缘网关TG453功能 部署在本地现…

Java学习之继承练习题

目录 第一题 代码 输出流程分析 运行结果 考察知识点 第二题 代码 流程分析 运行结果 第三题 题目要求 我的代码 代码改进 第一题 代码 package com.hspedu.extends_.exercise;public class ExtendsExercise01 {public static void main(String[] args) {B b new …

Mybatis Plus 多租户id使用

本文就不多逼逼&#xff0c;直接进入正题。 什么是多租户 多租户技术&#xff08;Multi-TenancyTechnology&#xff09;又称多重租赁技术&#xff0c;简称SaaS&#xff0c;是一种软件架构技术&#xff0c;是实现如何在多用户环境下 &#xff08;此处的多用户一般是面向企业用…

SpringCloud服务配置介绍Nacos实现管理配置

目录 一、服务配置中心介绍 二、Nacos config入门 三、Nacos config深入 四、Nacos的几个概念 一、服务配置中心介绍 首先我们来看一下,微服务架构下关于配置文件的一些问题&#xff1a; 配置文件相对分散。在一个微服务架构下&#xff0c;配置文件会随着微服务的增多变的…