代码随想录day23--回溯的应用2

LeetCode39.组合总和

题目描述:

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

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

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

示例 1:

输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

示例 2:

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

示例 3:

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

解题思路:

·这题的解题思路与之前的题目是一致的,是需要注意的是,这题含有重复元素这一定义,所以,再遍历的过程中,startIndex不需要想后移动

代码如下:

class Solution {
public: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);sum -= candidates[i];path.pop_back();}}vector<vector<int>> combinationSum(vector<int>& candidates, int target) {if(candidates.size() == 0) return result;backtracking(candidates,target,0,0);return result;}
};

·时间复杂度:O(n*2^n),注意这里只是时间复杂度的上界

·空间复杂度:O(target)

总结:这题与之前的题目有两点不同1.组合没有数量要求2.元素可无限重复选取

本题中使用startIndex来控制for循环的起始位置,对于组合问题中:

如果一个集合来求组合的话,就需要startIndex,例如之前写的77.组合,216.组合总和III

如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,例如之前的17.电话号码的字母组合

LeetCode40.组合总和II

题目描述:

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

解题思路:

·本题的难点在于,集合中可以有重复元素,但是不能有重复的组合,有些同学的想法是使用map或者set进行去重,但是这样使用并不能通过,所以我们要在搜索过程中去掉重复组合

·有很多同学不理解这里去重的意思,可以这样理解,就是使用过的元素不能重复使用。说起来是很简单的,但是如果抽象成树结构那么就不好思考出了,因为在树结构上,存在两个维度,一个维度是同一树杈上使用过,一个维度是同一树层次上使用过

·又有新的问题了,那么到底是选择同一树层上的,还是同一树杈上的,题目中说了,可以有重复的元素,但是不能有重复的组合,就可以列一个简单的例子,自己将树结构抽象画图出来,就明白了,如图:

·所以,我们要去重的是同一数层上使用过的,同一树枝上的都是一个组合内的元素,不用去重。

*特别强调,在对数组操作前,要将数组内元素进行排序

·我们使用一个bool型数组used,用于记录同一树枝上的元素是否使用过,若为true则未使用过,反之则使用过,因为已经将元素排序,所以当candidates[i] == candidates[i-1]并且used[i-1] == false,就说明前一个树枝使用了candidates[i-1],也就是说同一数层使用过candidates[i-1],则跳出循环,进行下一次遍历

*文字描述比较抽象,配合图片一起食用

代码如下:

class Solution {
public:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates,int target,int sum,int startIndex,vector<bool>& used){if(sum == target){result.push_back(path);return;}for(int i = startIndex;i < candidates.size()&&candidates[i]+sum <= target;i++){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);used[i] = false;path.pop_back();sum -= candidates[i];}}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;}
};

·时间复杂度:O(n*2^n)

·空间复杂度:O(n)

难点/易错点

·对元素去重的理解,是去除重复元素,还是去除重复组合

·没有对数组元素进行排序

·不知道如何确定元素是否被使用过

·停止搜索条件、递归条件、重复元素的定义

总结:因为这道题有去重这一步骤,所以这道题比之前做的回溯的题目更加的困难,关键是去重的逻辑,代码并不难理解,但是要把代码含义理解明白,这道题比较偏向逻辑,虽然是考察逻辑性,但是依旧是使用的回溯的基本模板。

LeetCode131.分割回文串

题目描述:

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

回文串 是正着读和反着读都一样的字符串。

示例 1:

输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]

示例 2:

输入:s = "a"
输出:[["a"]]

解题思路:

·切割问题类似组合问题

例如字符串abcdef:

1.组合问题:选取一个a之后,再bcdef中再去选取第二个,选取b之后再cdef中再选取第三个...

2.切割问题:切割一个a之后,再bcdef中再去切割第二段,切割b之后在cdef中再切割第三段...

·所以我们就可以将切割问题抽象成一棵树形结构:

·递归用来纵向遍历,for循环用来横向遍历,切割线(图中红线)切割到字符串的结尾位置,说明找到了一个切割方法。所以我们就可以发现,切割问题的回溯搜索的过程和则核问题的回溯搜索的过程是差不多的。

代码如下:

class Solution {
public:vector<vector<string>> result;vector<string> path;void backtracking(const string& s,int startIndex){if(startIndex >= s.size()){result.push_back(path);return ;}for(int i = startIndex;i < s.size();i++){if(huiwen(s,startIndex,i)){string str = s.substr(startIndex,i-startIndex+1);path.push_back(str);}else{continue;}backtracking(s,i+1);path.pop_back();}}bool huiwen(const string& s,int start,int end){for(int i = start,j = end;i < j;i++,j--){if(s[i] != s[j]){return false;}}return true;}vector<vector<string>> partition(string s) {backtracking(s,0);return result;}
};

·时间复杂度:O(n*2^n)

·空间复杂度:O(n^2)

难点:

·切割问题可以抽象成组合问题

·如何模拟哪些切割线

·切割问题总递归如何终止

·在递归循环中如何截取子串

·如何判断回文

总结:这道题可以说啥比较有难度了,有很多同学包括我自己,遇到题目知道比较难,但是不知道题目难在哪里。但是这样说明思维不够清晰。

之前在说明回溯法基础的时候说明了回溯法可以解决切割问题,但是在做这题的时候第一个i难点就是:不知道如何切割,甚至也不知道在哪里需要使用回溯法。也就是没有体会到按照组合问题的套路就可以解决切割。

但是接下来如何模拟切割线,如何终止,如何截取子串,都不好想,可以说是判断回文是最简单的了。

并且,需要搞明白,关于模拟切割线,其实就是index是上一层已经确定了的分割线,i是这一层试图寻找的新分割线。搞懂了这些,这道题其实也就没有那么难了。

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

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

相关文章

PyQt Python 使用 VTK ITK 进行分割 三维重建 医学图像可视化系统 流程

效果&#xff1a; 重建流程&#xff1a; 1. 输入 可以读取DICOM &#xff0c;nii nrrd 等数据 设置读取器以加载 DICOM 图像系列。 使用 itk::GDCMImageIO 作为 DICOM 图像的输入输出接口。 使用 itk::GDCMSeriesFileNames 获取指定路径下的所有 DICOM 文件名。 使…

Code Composer Studio (CCS) - Current and Local Revision

Code Composer Studio [CCS] - Current and Local Revision References 鼠标放在文件内的任意位置&#xff0c;鼠标右键 -> Compare With -> Local History -> Revision Time. References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

Doris ——SQL原理解析

目录 前言 一、Doris简介 二、SQL解析简介 2.1 词法分析 2.2 语法分析 2.3 逻辑计划 2.4 物理计划 三、Doris SQL解析的总体架构 四、Parse阶段 五、Analyze阶段 六、SinglePlan阶段&#xff08;生成单机逻辑Plan阶段&#xff09; 七、DistributedPlan计划&#xf…

SQL-Labs靶场“11-15”关通关教程

君衍. 一、十一关 基于POST单引号字符型注入1、源码分析2、联合查询注入3、报错注入 二、十二关 基于POST双引号字符型注入1、源码分析2、联合查询注入3、报错注入 三、十三关 基于POST单引号报错注入变形1、源码分析2、报错注入 四、十四关 基于POST双引号报错注入1、源码分析…

代码随想录day24--回溯的应用3

LeetCode93.修复IP地址 题目描述&#xff1a; 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 . 分隔。 例如&#xff1a;"0.1.2.201" 和 "192.168.1.1" 是…

使用八叉树模拟水和烟雾 Simulating Water and Smoke with an Octree Data Structure 论文阅读笔记

原文&#xff1a; Losasso, Frank, Frdric Gibou, and Ron Fedkiw. “Simulating water and smoke with an octree data structure.” Acm siggraph 2004 papers. 2004. 457-462. 引言 这篇文章扩展了 [Popinet 2003] 的工作&#xff0c;拓展到表面自由流&#xff0c;并且使…

Oracle 基础入门指南

一、什么是Oracle&#xff1f; Oracle是一款由美国Oracle公司开发的关系型数据库管理系统。它支持SQL查询语言&#xff0c;并提供了丰富的功能和工具&#xff0c;用于管理大规模数据存储、处理和访问。Oracle被广泛应用于企业级应用中&#xff0c;包括金融、电信、零售等各行各…

第12章 反射

12.1 反射概述 Java的反射&#xff08;reflection&#xff09;机制是指在程序的运行状态中&#xff0c;可以构造任意一个类的对象&#xff0c;可以得到任意一个对象所属的类的信息&#xff0c;可以调用任意一个类的成员变量和方法&#xff0c;可以获取任意一个对象的属性和方法…

js---webAPI

01 声明变量 js组成&#xff1a; DOM:操作网页内容的,开发页面内容特效和实现用户交互 BOM: DOM树&#xff1a;将 HTML 文档以树状结构直观的表现出来&#xff0c;我们称之为文档树或 DOM 树 文档树直观的体现了标签与标签之间的关系 CSS获取元素的方法 document.querySele…

精品springboot基于大数据的电脑主机硬件选购助手-可视化大屏

《[含文档PPT源码等]精品基于springboot基于大数据的电脑主机硬件选购助手[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; Java——涉及技术&#xff1a; 前端使用技术&a…

Cron表达式选择器

Cron表达式选择器 功能描述 Cron表达式选择器是用于定时任务调度的一种常见工具&#xff0c;通常用于指定任务的执行时间。Cron表达式由一系列时间单位和对应的时间值组成&#xff0c;用于指定任务的执行时间。下面是一个Cron表达式的示例 0 0 12 * * ?这个表达式的含义是每…

电阻器的脉冲浪涌能力?

由于现有需求&#xff0c;许多现代电子电路和设备都会经历瞬态脉冲和浪涌。这反过来又导致需要“设计”瞬态浪涌保护&#xff0c;尤其是在电机控制器等电路中。当电机启动时&#xff0c;此时消耗的电流过大&#xff0c;可能导致电阻器故障。同样&#xff0c;如果电容器用于电机…

【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱13(附带项目源码)

效果演示 文章目录 效果演示前言每次丢弃一个物品源码完结前言 欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第25篇中,我们将探索如何用unity制作一个3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机…

MySQL性能分析1

1、查看执行频次 查看当前数据库的INSERT,UPDATE,DELETE,SELECT的访问频次&#xff0c;得到当前数据库是以插入&#xff0c;更新和删除为主还是以查询为主&#xff0c;如果是以插入&#xff0c;更新和删除为主的话&#xff0c;那么优化比重可以轻一点儿。 语法&#xff1a; …

Qt实用技巧:QCustomPlot做北斗GPS显示绝对位置运动轨迹和相对位置运动轨迹图的时,使图按照输入点顺序连曲线

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/136131310 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

适用于 Windows 的 12 个最佳 PDF 编辑器

PDF文档的普遍存在按理说&#xff0c;PDF文档的可读性和可移植性受到专业文档的青睐。 然而&#xff0c;PDF格式的可食用性是一大缺陷。幸运的是&#xff0c;各种 PDF 编辑工具和软件使 PDF 的编辑变得更加容易&#xff0c;这篇文章旨在帮助我们的读者找到其中最好的工具和软件…

CSS的注释:以“ /* ”开头,以“ */ ”结尾

CSS的注释:以“ /* ”开头&#xff0c;以“*/”结尾 CSS的注释: 以“ /* ”开头&#xff0c;以“ */ ”结尾 在CSS中&#xff0c;注释是一种非常重要的工具&#xff0c;它们可以帮助开发者记录代码的功能、用法或其他重要信息。这些信息对于理解代码、维护代码以及与他人合作都…

JS进阶——垃圾回收机制以及算法

版权声明 本文章来源于B站上的某马课程&#xff0c;由本人整理&#xff0c;仅供学习交流使用。如涉及侵权问题&#xff0c;请立即与本人联系&#xff0c;本人将积极配合删除相关内容。感谢理解和支持&#xff0c;本人致力于维护原创作品的权益&#xff0c;共同营造一个尊重知识…

IDM6.42.3下载器(Internet Download Manager)俄罗斯大神版,

IDM下载器&#xff08;Internet Download Manager&#xff09;俄罗斯大神版&#xff0c;目前最新版是 6.42.3。 Internet Download Manager&#xff08;简称&#xff1a;IDM&#xff09;是一款来自国外的非常优秀网络资源高速下载及管理工具&#xff0c;该软件同时是一款收费共…

计算机毕业设计SSM基于的高校学习资源共享系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; vue mybatis Maven mysql5.7或8.0等等组成&#xff0c;B…