Studying-代码随想录训练营day23| 39.组合总和、40.组合总和II、131.分割回文串

第23天,回溯part02,回溯两个题型组合,切割(ง •_•)ง💪

目录

39.组合总和

40.组合总和II

131.分割回文串 

总结 


39.组合总和

文档讲解:代码随想录组合总和

视频讲解:手撕组合总和

题目:

学习:

本题是在一个数组中抽取数加起来的和为target,与昨天的k个数的题目不同,昨天的题目中数的个数k限制了递归的层数,本题则是target限制了递归的层数。

同时要注意本题允许同一个数字无限制重复取用,因此每一层循环的范围要包含该节点,将本题的回溯逻辑转化为一张树形图为:

代码:确定回溯三部曲

//时间复杂度O(n*2^n)
//空间复杂度O(target)
class Solution {
public:vector<vector<int>> result; //答案数组vector<int> path; //保存路径//确定返回值和参数,本题有保存路径和答案数组因此不需要返回值,参数需要原数组,目标值target,一个集合范围下标startindex,一个求和sumvoid backtracking(vector<int>& candidates, int target, int startindex, int sum) {//确定终止条件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, i, sum);//回溯sum -= candidates[i];path.pop_back();}}vector<vector<int>> combinationSum(vector<int>& candidates, int target) {backtracking(candidates, target, 0, 0);return result;}

剪枝优化:本题显然能够针对sum进行优化,但优化前还需要注意要先对数组candidates进行排序,便于进行剪枝。

class Solution {
public:vector<vector<int>> result; //答案数组vector<int> path; //保存路径//确定返回值和参数,本题有保存路径和答案数组因此不需要返回值,参数需要原数组,目标值target,一个集合范围下标startindex,一个求和sumvoid backtracking(vector<int>& candidates, int target, int startindex, int sum) {//确定终止条件if(sum == target) {result.push_back(path);return;}//确定单层递归逻辑//剪枝处理,缩小for循环范围for(int i = startindex; i < candidates.size() && sum + candidates[i] <= target; i++) {sum += candidates[i];path.push_back(candidates[i]);backtracking(candidates, target, i, sum);//回溯sum -= candidates[i];path.pop_back();}}vector<vector<int>> combinationSum(vector<int>& candidates, int target) {//进行排序,进行剪枝sort(candidates.begin(), candidates.end());backtracking(candidates, target, 0, 0);return result;}
};

40.组合总和II

文档讲解:代码随想录组合总和II

视频讲解:手撕组合总和II

题目:

学习:

本题实际上和我们之前所学的三数之和,四数之和有些相似,那两题能够通过有限的循环找到答案。本题没有确定数的个数,因此本题不能直接通过有限个循环求解,需要采用回溯的方法。

本题的难点在于遍历过程中我们还需要进行去重处理,但这可以参考我们在三数之和里面进行的去重。关键在于当前遍历的数和前一个数相等时,当前的遍历就可以跳过,因为从当前往后遍历的所有可能的情况,前一个数都已经遍历过了,为了避免重复就可以跳过当前的循环。(要注意去重之前还需要对数组进行排序!)

上述的去重方式可以理解为树层去重,同一层相同的数可以进行去重,而同一个树枝上的组合里的元素不需要去重,因为一个组合是允许有相同的树的。

本题的剪枝和上一题相同,本题采用对target作减法的方式找到答案组合,因此当target小于0时就可以进行返回了,缩减for循环范围:

代码:确定回溯三部曲

//时间复杂度O(n*2^n)
//空间复杂度O(n)
class Solution {
public://本题和三数之和十分相似,但三数之和规定了三个数,本题没有规定数的个数限制,无法确定循环层数,因此需要使用回溯vector<vector<int>> result; //答案数组vector<int> path; //保存路径//确定返回值和参数,本题直接在答案数组中进行操作,因此不需要返回值,参数需要给的数组,目标值,和一个指示范围的值//这里我们采用使用target作减法的方式,来进行和的求解void backtracking(vector<int>& candidates, int target, int startindex) {//确定终止条件if(target == 0) {result.push_back(path);}//确定单层递归逻辑//对范围进行剪枝for(int i = startindex; i < candidates.size() && target - candidates[i] >= 0; i++){//对结果去重,如果后面遍历的数有和前面的相同,则跳过它,因为前面相同的数已经把后面的结果遍历完了if(i > startindex && candidates[i] == candidates[i - 1]) continue;path.push_back(candidates[i]);target -= candidates[i];backtracking(candidates, target, i + 1);path.pop_back();target += candidates[i];}}vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {//排序便于进行去重sort(candidates.begin(), candidates.end());backtracking(candidates, target, 0);return result;}
};

131.分割回文串 

文档讲解:代码随想录分割回文串

视频讲解:手撕分割回文串

题目:

学习:

本题是回溯算法中切割的第一道题,题干虽然很短,但实际难度很大。我们可以将问题分为几个步骤:1.如何切割字符串;2.如何遍历不同的切割方式;3.如何判断字符串是否回文。

针对以上三个问题,前两个实际上可以看作是一个组合的问题,即如何分开不同的数和如何不重复的遍历所有的情况。而第三个问题则是在循环过程中需要进行判断的,因此本题的回溯逻辑用树形结构可以写为:

可以看出切割的回溯搜索的过程实际上和组合问题的回溯搜索过程是差不多的。本题重点需要关注的是如何确定切割线以及如何截取子串。

  • 如何确定切割线:由图中我们可以看出,实际上每一层的切割线都是由startindex确定的,例如循环的第一层startindex=0,切割线排在最前面,因此每次都至少包含第一个字母a。而第二层对于最左边的节点来说startindex=1,切割线在第二个字母,前面的字符串已经确定了,之后的每次切割都包含第二个字母(由于ab不是回文所以不进行循环)。
  • 如何截取子串:确定了切割线的位置,子串的终点实际就是我们遍历过程中的i,i的变化决定了子串的长度,例如第一层来说,i从0到3,切割出来的子串就是a,aa,aab。子串就可以表示为字符串s中[startindex, i]区间包含的元素。

最后判断回文串,可以通过一个函数进行, 使用双指针法,一个指针从前向后,一个指针从后向前,如果前后指针所指向的元素是相等的,就是回文字符串了。最后的代码如下:

代码:确定回溯三部曲

//时间复杂度O(n*n^2)
//空间复杂度O(n^2)
class Solution {
public:vector<vector<string>> result; //返回数组vector<string> path; //保存路径//确定返回值和参数,本题同样不需要返回值,参数中除了字符串s以外,还需要一个起始下标startindex//这里十分要注意startindex就是切割线void backtracking(string s, int startindex) {//确定终止条件,当切割线等于字符串长度,意味着最后也切割完成了if(startindex == s.size()) {result.push_back(path);return;}//确定单层递归逻辑for(int i = startindex; i < s.size(); i++) {//以startindex为切割线一直到i为字符串长度//如果是回文串的话,假如path当中if(Palindrome(s, startindex, i)) {//获取[startindex,i]在s中的子串,第一个参数为下标位置,第二个参数为长度string str = s.substr(startindex, i - startindex + 1);path.push_back(str);}else {continue;}backtracking(s, i + 1); //切割下一个字符串path.pop_back(); //回溯}}//判断是否是回文字符串bool Palindrome(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;}
};

总结:本题的难点主要有:切割问题可以抽象为组合问题、如何模拟那些切割线、切割问题中递归如何终止、在递归循环中如何截取子串、如何判断回文。理解这几点本题也就能够解出来了。


总结 

回溯算法是一个暴力搜索的方法,因此我们重点要理解每一道题暴力搜索的逻辑过程,才能够写出正确的回溯算法代码,多加练习💪。

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

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

相关文章

【Qt】信号和槽机制

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

WINDOWS+PHP+Mysql+Apache环境中部署SQLi-Labs、XSS-Labs、UPload-Labs、DVWA、pikachu等靶场环境

web渗透测试学习&#xff0c;需要自己搭建一些靶场&#xff0c;本人主要介绍在WINDOWSPHPMysqlApache环境中部署SQLi-Labs、XSS-Labs、UPload-Labs、DVWA、pikachu等靶场环境。以下是靶场代码下载的链接&#xff1a; pikachu靶场代码 链接&#xff1a;https://pan.baidu.com/s…

废品回收小程序开发:提高废品回收效率

当下&#xff0c;废品回收已经成为了热门行业&#xff0c;家家户户几乎都会进行废品回收&#xff0c;无论是废纸盒还是塑料瓶等&#xff0c;都会送到废品回收站。不过&#xff0c;随着互联网的快速发展&#xff0c;传统的回收模式出现了大量的局限性&#xff0c;已经不能满足大…

探索Android架构设计

Android 应用架构设计探索&#xff1a;MVC、MVP、MVVM和组件化 MVC、MVP和MVVM是常见的三种架构设计模式&#xff0c;当前MVP和MVVM的使用相对比较广泛&#xff0c;当然MVC也并没有过时之说。而所谓的组件化就是指将应用根据业务需求划分成各个模块来进行开发&#xff0c;每个…

领夹麦克风哪个品牌音质最好?主播一般用什么麦克风?麦克风推荐

在这个充满创意与表达的时代&#xff0c;无线领夹麦克风以其独特的魅力&#xff0c;成为了声音创作者们的得力助手。它小巧便携&#xff0c;功能强大&#xff0c;无论是日常拍摄、直播互动还是专业演出&#xff0c;都能轻松应对&#xff0c;让你的声音随时随地清晰传递。那么&a…

# Kafka_深入探秘者(10):kafka 监控

Kafka_深入探秘者&#xff08;10&#xff09;&#xff1a;kafka 监控 一、kafka JMX 1、JMX &#xff1a;全称 Java Managent Extension 在实现 Kafka 监控系统的过程中&#xff0c;首先我们要知道监控的数据从哪来&#xff0c;Kafka 自身提供的监控指标(包括 broker 和主题的…

管理的核心是管人,管人的核心就是这3条,看懂的是高手

管理的核心是管人&#xff0c;管人的核心就是这3条&#xff0c;看懂的是高手 一&#xff1a;管欲 每个人都有欲望&#xff0c;无可厚非。管理者的任务就是利用欲望&#xff0c;管理欲望&#xff0c;通过欲望来达到管人的目的。 最需要管理的就是以下两种&#xff1a; 1、金…

普乐蛙景区9d电影体验馆商场影院娱乐设备旋转飞行影院

今天与大家聊聊VR娱乐新潮流&#xff0c;我们普乐蛙的新品——旋转飞行影院&#xff01;裸眼7D环幕影院&#xff0c;话不多说上产品&#xff01;我们通过亲身体验来给大家讲讲这款高性价比新品的亮点。 想象一下走上电动伸缩梯&#xff0c;坐进动感舱&#xff0c;舱门缓缓合上&…

点击获取2024SIAL西雅国际食品展上海展后报告

随着2024年SIAL 西雅展&#xff08;上海&#xff09;的圆满落幕&#xff0c;我们不仅见证了一场食品与饮料行业的国际盛会&#xff0c;更是感受到了上海这座城市独有的魅力与活力。在这里&#xff0c;我们回顾了上海展的辉煌成就&#xff0c;同时&#xff0c;我们也满怀期待地展…

第4章 客户端-客户端管理

1. 客户端API 1.1client list client list命令能列出与Redis服务端相连的所有客户端连接信息。 127.0.0.1:6379> client list id254487 addr10.2.xx.234:60240 fd1311 name age8888581 idle8888581 flagsN db0 sub0 psub0 multi-1 qbuf0 qbuf-free0 obl0 oll0 omem0 events…

MySQL数据库基础练习系列——教务管理系统

项目名称与项目简介 教务管理系统是一个旨在帮助学校或教育机构管理教务活动的软件系统。它涵盖了学生信息管理、教师信息管理、课程管理、成绩管理以及相关的报表生成等功能。通过该系统&#xff0c;学校可以更加高效地处理教务数据&#xff0c;提升教学质量和管理水平。 1.…

5款提高工作效率的免费工具推荐

SimpleTex SimpleTex是一款用于创建和编辑LaTeX公式的简单工具。它能够识别图片中的复杂公式并将其转换为可编辑的数据格式。该软件提供了一个直观的界面&#xff0c;用户可以在编辑LaTeX代码的同时实时预览公式的效果&#xff0c;无需额外的编译步骤。此外&#xff0c;SimpleT…

生命在于学习——Python人工智能原理(2.5.1)

五、Python的类与继承 5.1 Python面向对象编程 在现实世界中存在各种不同形态的事物&#xff0c;这些事物之间存在各种各样的联系。在程序中使用对象来映射现实中的事物&#xff0c;使用对象之间的关系描述事物之间的联系&#xff0c;这种思想用在编程中就是面向对象编程。 …

C++笔记:实现一个字符串类(构造函数、拷贝构造函数、拷贝赋值函数)

实现一个字符串类String&#xff0c;为其提供可接受C风格字符串的构造函数、析构函数、拷贝构造函数和拷贝赋值函数。 声明依赖文件 其中ostream库用于打印标准输入输出&#xff0c;cstring库为C风格的字符串库 #include <iostream> #include <cstring> 声明命…

【python】OpenCV—Color Correction

文章目录 cv2.aruco 介绍imutils.perspective.four_point_transform 介绍skimage.exposure.match_histograms 介绍牛刀小试遇到的问题 参考学习来自 OpenCV基础&#xff08;18&#xff09;使用 OpenCV 和 Python 进行自动色彩校正 cv2.aruco 介绍 一、cv2.aruco模块概述 cv2.…

骨传导耳机哪个牌子值得入手?精选热销榜TOP5推荐!

短短数年&#xff0c;骨传导耳机的市场规模迅速扩大&#xff0c;其受欢迎程度可见一斑。但身为拥有十二年经验的音频专家&#xff0c;我在此有义务提醒大家&#xff0c;在选择骨传导耳机时一定要谨慎。面对市面上的众多品牌&#xff0c;一定不要盲目入手&#xff0c;不然很容易…

leetcode提速小技巧

据我所知&#xff0c;leetcode可能是按最难那个用例给你打分的&#xff0c;非难题的用时好坏不完全看复杂度&#xff0c;因为可能都差不多&#xff0c;O(n/2)和O(n)虽然都是O(n)&#xff0c;但是反应到成绩上是不同的&#xff0c;所以&#xff0c;尽可能的在条件足够的情况下提…

Java鲜花下单预约系统源码小程序源码

让美好触手可及 &#x1f338;一、开启鲜花新篇章 在繁忙的都市生活中&#xff0c;我们总是渴望那一抹清新与美好。鲜花&#xff0c;作为大自然的馈赠&#xff0c;总能给我们带来无尽的惊喜与愉悦。但你是否曾因为工作繁忙、时间紧张而错过了亲自挑选鲜花的机会&#xff1f;今…

KVB交易平台: 美元兑日元升破161,这一趋势会继续吗?

在2024年6月28日&#xff0c;美元在亚洲交易市场中表现强劲&#xff0c;接近四十年来的新高&#xff0c;预计将连续第二个季度上涨。与此同时&#xff0c;日本日元持续走低&#xff0c;跌至38年以来的新低&#xff0c;首次突破161关口。在东京交易中&#xff0c;日元兑美元贬值…

小程序反编译后报错“_typeof3 is not a function”

详情->本地设置->取消勾选“将JS编译成ES5” 参考链接&#xff1a;https://blog.csdn.net/csl12919/article/details/131569914