leetcode算法刷题的第二十天

1.leetcode 39.组合总和

题目链接

这道题里面的数组里面的数字是可以重复使用的,那可能就会有人想,出现了0怎么办,有这个想法的很好,但是题目要求数组里面的数字最小值为1,这就可以让人放心了。但是有总和的限制,所以间接的也有个数的限制。

因为没有个数的限制,所以可能递归没有层数的限制,但是只要选取的元素总和超过了target,就返回。

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);// 不用i+1了,表示可以重复读取当前的数sum-=candidates[i];path.pop_back();}}vector<vector<int>> combinationSum(vector<int>& candidates, int target) {backtracking(candidates,target,0,0);return result;}
};

思路总结:这道题有两点不同:组合没有数量要求以及元素可以无限重复选取。

2.leetcode 40.组合总和II

题目链接

这道题和上一道题目的区别:第一,本题的数组中的每个数字在每个组合中只能使用一次,第二,本题数组的元素是有重复的,而上一题是无重复元素的数组。

最后本题和上一道题的要求是一样的,解集不能包含重复的组合。

本题的难点在于区别2中:集合(数组candidates)有重复元素,但还不能有重复的组合

一些同学可能想了:我把所有组合求出来,再用set或者map去重,这么做很容易超时!

所以要在搜索的过程中就去掉重复组合。

很多同学在去重的问题上想不明白,其实很多题解也没有讲清楚,反正代码是能过的,感觉是那么回事,稀里糊涂的先把题目过了。

这个去重为什么很难理解呢,所谓去重,其实就是使用过的元素不能重复选取。 这么一说好像很简单!

都知道组合问题可以抽象为树形结构,那么“使用过”在这个树形结构上是有两个维度的,一个维度是同一树枝上使用过,一个维度是同一树层上使用过。没有理解这两个层面上的“使用过” 是造成大家没有彻底理解去重的根本原因。

那么问题来了,我们是要同一树层上使用过,还是同一树枝上使用过呢?

回看一下题目,元素在同一个组合内是可以重复的,怎么重复都没事,但两个组合不能相同。

所以我们要去重的是同一树层上的“使用过”,同一树枝上的都是一个组合里的元素,不用去重

为了理解去重我们来举一个例子,candidates = [1, 1, 2], target = 3,(方便起见candidates已经排序了)

强调一下,树层去重的话,需要对数组排序!

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()&&sum+candidates[i]<=target;i++){// used[i - 1] == true,说明同一树枝candidates[i - 1]使用过// used[i - 1] == false,说明同一树层candidates[i - 1]使用过// 要对同一树层使用过的元素进行跳过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);// 和39.组合总和的区别1,这里是i+1,每个数字在每个组合中只能使用一次used[i]=false;sum-=candidates[i];path.pop_back();}}vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {vector<bool> used(candidates.size(),false);// 首先把给candidates排序,让其相同的元素都挨在一起。sort(candidates.begin(),candidates.end());backtracking(candidates,target,0,0,used);return result;}
};

补充:这里直接使用startIndex来去重也是可以的,就可以不用used数组。

class Solution {
public: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;}for(int i=startIndex;i<candidates.size()&&sum+candidates[i]<=target;i++){// 要对同一树层使用过的元素进行跳过if(i>startIndex&&candidates[i]==candidates[i-1]){continue;}sum+=candidates[i];path.push_back(candidates[i]);backtracking(candidates,target,sum,i+1);// 和39.组合总和的区别1,这里是i+1,每个数字在每个组合中只能使用一次sum-=candidates[i];path.pop_back();}}vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {// 首先把给candidates排序,让其相同的元素都挨在一起。sort(candidates.begin(),candidates.end());backtracking(candidates,target,0,0);return result;}
};

思路总结:关键是去重的逻辑,代码很简单,网上一搜一大把,但几乎没有能把这块代码含义讲明白的,基本都是给出代码,然后说这就是去重了,究竟怎么个去重法也是模棱两可。

3.leetcode 131.分割回文串

题目链接

回文串就是向前和向后读都是相同的字符串。

本题涉及到两个关键问题:第一,切割问题,有不同的切割方式,第二,判断回文。

我们来分析一下切割,其实切割问题类似组合问题

例如对于字符串abcdef:

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

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

class Solution {
public:vector<vector<string>> result;vector<string> path;// 放已经回文的子串//判断是否为回文串bool isH(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;}void backtracking(const string& s,int startIndex){// 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了if(startIndex>=s.size()){result.push_back(path);return;}for(int i=startIndex;i<s.size();i++){if(isH(s,startIndex,i)){// 是回文子串// 获取[startIndex,i]在s中的子串string str=s.substr(startIndex,i-startIndex+1);path.push_back(str);}else{// 不是回文,跳过continue;}backtracking(s,i+1);// 寻找i+1为起始位置的子串path.pop_back();// 回溯过程,弹出本次已经添加的子串}}vector<vector<string>> partition(string s) {backtracking(s,0);return result;}
};

思路总结:

这道题目在leetcode上是中等,但可以说是hard的题目了,但是代码其实就是按照模板的样子来的。

那么难究竟难在什么地方呢?

我列出如下几个难点:

  • 切割问题可以抽象为组合问题
  • 如何模拟那些切割线
  • 切割问题中递归如何终止
  • 在递归循环中如何截取子串
  • 如何判断回文

我们平时在做难题的时候,总结出来难究竟难在哪里也是一种需要锻炼的能力

一些同学可能遇到题目比较难,但是不知道题目难在哪里,反正就是很难。其实这样还是思维不够清晰,这种总结的能力需要多接触多锻炼。

本题我相信很多同学主要卡在了第一个难点上:就是不知道如何切割,甚至知道要用回溯法,也不知道如何用。也就是没有体会到按照求组合问题的套路就可以解决切割

如果意识到这一点,算是重大突破了。接下来就可以对着模板照葫芦画瓢。

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

关于模拟切割线,其实就是index是上一层已经确定了的分割线,i是这一层试图寻找的新分割线

除了这些难点,本题还有细节,例如:切割过的地方不能重复切割所以递归函数需要传入i + 1

所以本题应该是一道hard题目了。

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

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

相关文章

使用Spoon报错Driver class ‘com.microsoft.sqlserver.jdbc.SQLServerDriver‘ could not be found解决方法

使用Spoon报错Driver class ‘com.microsoft.sqlserver.jdbc.SQLServerDriver’ could not be found 产生原因 出现这个错误是因为Spoon无法找到用于连接MS SQL Server的JDBC驱动程序。该驱动程序是一个jar文件,通常需要手动下载并配置。 解决方案 下载JDBC驱动程序: 访问 M…

【实时Linux实战系列】基于实时Linux的音频实时监控系统

在当今数字化时代&#xff0c;音频监控系统在许多领域都有着广泛的应用&#xff0c;例如安全监控、工业环境监测、智能交通等。音频实时监控系统能够实时采集、分析音频信号&#xff0c;并在检测到异常时发出警报&#xff0c;这对于提高安全性、优化生产流程和提升用户体验都有…

改造thinkphp6的命令行工具和分批次导出大量数据

文章目录基本用法传入参数addArgumentaddOption参数提示导出数据示例准备工作执行导出基本用法 在thinkphp6框架中&#xff0c;自带了命令行工具&#xff0c;通过配置 config/console.php &#xff0c;添加自定义的命令&#xff1a; return [commands > [//...//新增的自定…

外汇中高频 CTA 风控策略回测案例

在汇率波动日益频繁、企业与机构对风险管理要求不断提高的背景下&#xff0c;外汇交易策略已成为资产配置与对冲操作的重要工具。其中&#xff0c;CTA 策略在外汇交易中具有非常重要的实际应用价值&#xff0c;在风险控制、趋势捕捉、资金效率与交易实用性之间取得了良好平衡。…

【iOS】内存管理及部分Runtime复习

1.继承链关于继承链存在两个指针 类的superclass指向父类 父类的sp指向根类 根类的sp指向空 元类的sp指向父类的元类 最终指向根元类 而根元类的sp指向根类 而关于isa指针 对象的isa指针指向它所属的类 类的isa指针指向元类 元类的isa指针指向根元类 根元类的isa指针指向自己2.…

重置 Windows Server 2019 管理员账户密码

文章目录前言1. 重置方法2. 重置流程总结前言 之前因为参加华为存储的 HCIE 培训和考试&#xff0c;以及在项目上交付和运维&#xff0c;占用了较多的时间和精力&#xff0c;导致很长一段时间没有去写博客&#xff0c;前些天登录 CSDN 博客发现原力已失效&#xff0c;才知道平…

.Net Core Web 架构(管道机制)的底层实现

.Net Core Web 架构(管道机制)的底层实现 .NET Core Web 程序的底层实现是一个复杂的体系&#xff0c;但我们可以将其分解为几个核心部分来理解。它本质上是一个将 HTTP 请求转换为开发者代码执行&#xff0c;并将执行结果返回为 HTTP 响应的精密管道。 下图清晰地展示了这一处…

计算图的力量:从 PyTorch 动态图到 TensorFlow 静态图的全景与实战

计算图的力量:从 PyTorch 动态图到 TensorFlow 静态图的全景与实战 开篇引入 Python 从简洁优雅的脚本语言,成长为连接数据科学、机器学习与工程化部署的“胶水语言”。在这段进化中,深度学习框架把“数学表达式”变成可执行的“计算图”,让自动求导与高性能并行成为日常…

CentOS 7能联网但yum报错:Could not resolve host: mirrorlist.centos.org 终极解决方法

CentOS 7能联网但yum报错&#xff1a;Could not resolve host: mirrorlist.centos.org 终极解决方法关键词&#xff1a;CentOS 7, yum, Could not resolve host, mirrorlist.centos.org, 软件源, EOL问题描述大家好&#xff01;相信很多还在使用 CentOS 7 的朋友都遇到了这个问…

【解锁Photonics for AI:系统学习光学神经网络与超表面设计,成就下一代光芯片工程师】

### 光学神经网络基础 光学神经网络利用光子替代电子进行信息处理&#xff0c;具有低延迟、高带宽和低功耗优势。核心组件包括衍射光学元件&#xff08;DOE&#xff09;、马赫-曾德尔干涉仪&#xff08;MZI&#xff09;和微环谐振器。 衍射神经网络&#xff08;DNN&#xff09…

基于SrpingBoot和Vue的共享笔记管理系统-项目分享

基于SrpingBoot和Vue的共享笔记管理系统-项目分享项目介绍项目摘要用户管理实体图笔记分享管理实体图系统总体功能图写在最后项目介绍 使用者&#xff1a;管理员、用户 开发技术&#xff1a;MySQLJavaSpringBootVue 项目摘要 随着网络技术的普及和人们阅读习惯的改变&#x…

我的6年!

修改前&#xff1a;https://t.zsxq.com/ERUuD Data&#xff1a;2025/08/27 更新 你好&#xff0c;我是老成。我在星球中用红包&#x1f9e7;的方式鼓励大家发自我介绍&#xff0c;但是我又想&#xff0c;为带动大家&#xff0c;我得做个榜样&#xff0c;为此我重新修改一下我的…

深入理解事务一致性和隔离性

事务是数据库系统提供的高级抽象&#xff0c;利用事务可以让应用层付出较少的努力就能提供较高的一致性保障&#xff0c;而不用过度关心类似于竞争条件、不完全写入、数据丢失等问题。 稍微学过用过数据库的同学&#xff0c;大都接触过事务这个概念&#xff0c;通常也知道事务…

最优化方法学习笔记

什么是“最优化”&#xff1f;最优化方法的核心思想是&#xff1a;在给定的条件下&#xff0c;找到一个最佳的解决方案。这个“最佳”通常是指使得某个目标函数&#xff08;可以是最小化或最大化的数值&#xff09;达到极致的答案。简单来说&#xff0c;就是如何用最好的方式做…

多模态融合新纪元:Ovis2.5 本地部署教程,实现文本、图像与代码的深度协同推理

一、简介Ovis2.5 旨在实现原生分辨率的视觉感知和增强的多模态推理。它集成了一个原生分辨率的视觉变换器&#xff08;NaViT&#xff09;&#xff0c;可以处理原始、可变分辨率的图像&#xff0c;消除了固定分辨率切片的需要&#xff0c;并保留了精细细节和全局布局——这对于图…

力扣hot100:滑动窗口最大值优化策略及思路讲解(239)

记录一下今天完成的算法题&#xff0c;虽然这个难度是困难&#xff0c;但感觉没有那个560.和为k的子数组和难想&#xff0c;这个题主要就前期遇到个优先队列&#xff0c;因为之前没用过&#xff0c;不太熟悉&#xff0c;剩下的思路感觉都属于正常难度问题描述原始思路&#xff…

“互联网 +”时代下开源 AI 大模型 AI 智能名片 S2B2C 商城小程序:行业变革与未来展望

摘要&#xff1a;在“互联网 ”浪潮的推动下&#xff0c;各行业正经历着深度融合与变革。互联网、新零售、云计算等新兴技术成为行业发展的关键驱动力。本文聚焦开源 AI 大模型 AI 智能名片 S2B2C 商城小程序这一创新模式&#xff0c;分析其在“互联网 ”背景下的内涵与优势&am…

ROS2通信机制实战——从“单向传数据”到“双向发请求”(二)

第2天&#xff1a;ROS2通信机制实战——从“单向传数据”到“双向发请求” 做机器人开发时&#xff1a;“为什么控制机器人前进用话题&#xff0c;而让机器人报位置要用服务&#xff1f;”其实答案很简单——ROS2的通信机制是“按需设计”的&#xff1a;话题适合高频、单向的数…

Function Calling(智能客服)

目录 1.0.思路分析 1.1.基础CRUD 1.1.1.数据库表 1.1.2.引入依赖 1.1.3.配置数据库 1.1.4.基础代码 2.定义Function 2.1.课程表的字段&#xff1a; 2.2.定义Function 2.3.System提示词 2.4.配置ChatClient 3.编写Controller 3.1.解决兼容性问题 3.2.AlibabaOpenA…

探索淀粉深加工的无限可能:2026 济南展览会前瞻

在全球农产品加工的广阔版图中&#xff0c;淀粉深加工产业犹如一颗璀璨的明珠&#xff0c;散发着日益耀眼的光芒。其产品广泛渗透于食品、饮料、医药、化工、能源等诸多领域&#xff0c;宛如一条条无形的纽带&#xff0c;将各个行业紧密相连。随着技术的日新月异、政策的大力扶…