Studying-代码随想录训练营day24| 93.复原IP地址、78.子集、90.子集II

第24天,回溯算法part03,牢记回溯三部曲,掌握树形结构结题方法💪

目录

93.复原IP地址

78.子集

90.子集II

总结 


93.复原IP地址

文档讲解:代码随想录复原IP地址

视频讲解:手撕复原IP地址

题目:

学习:本题属于切割类问题,不同的是本题需要使用 ' · ’ 来切割,并且本题对切割的数字大小和多少,切割多少次都有要求。但本质都是两步:1.切割;2.判断切割是否正确。

依据以上两点,本题和131.分割回文串不同的地方就在于对分割部分的判断和终止条件的选择。回溯逻辑用树形结构来表示为:

注意:判断分割部分是否合法,主要从三个部分出发:1.段位以0为开头且不止有0的数字不合法。2.段位里有非正整数字符不合法。3.段位如果大于255了不合法。

代码:确定回溯三部曲,注意本题要在字符串中加入' . ' 因此回溯的时候要删掉该点。

//时间复杂度O(3^4)
//空间复杂度O(n)
class Solution {
public://直接在字符串上进行操作,因此不设置路径数组vector<string> result; //返回数组//确定返回值和参数列表,直接在答案数组中插入因此不需要返回值,参数中需要原字符串s,分割点startindex//本题还需要一个int型变量point表示当前逗号的数量void backtracking(string& s, int startindex, int point) {//确定终止条件,当逗号数量为3个时,说明当前分割已经完成了if(point == 3) {//最后一部分字符串还需要进行判断if(ipvaild(s, startindex, s.size() - 1)) {result.push_back(s);}return;}//确定单层递归逻辑for(int i = startindex; i < s.size(); i++) {//startindex作为切割线,切割的字符串区间为[startindex, i],左闭右闭//判断切割下来的字符串是否合理if(ipvaild(s, startindex, i)){//如果合理的话,在字符串下标i后插入逗号,并进行下一轮递归s.insert(s.begin() + i + 1, '.');point++;//注意这里需要传入的是i+2,因为加了一个逗号,切割的位置需要往后移两位backtracking(s, i + 2, point);point--; //回溯s.erase(s.begin() + i + 1);}else {  //假如不满足,后续的切割方法也难以满足,直接跳出本层循环break;}}}bool ipvaild(string& s, int start, int end) {if (start > end) {return false;}//如果存在前置0的话,返回falseif(start != end && s[start] == '0') {return false;}int num = 0; //对切割字符串进行求和for(int i = start; i <= end; i++) {if(s[i] - '0' < 0 || s[i] - '0' > 9) {return false;}num = num * 10 + (s[i] - '0');if(num > 255) {return false;}}return true;}vector<string> restoreIpAddresses(string s) {backtracking(s, 0, 0);return result;}
};

本题可以进行剪枝,自认为本题可以从三个部分进行剪枝,分别是:1.剪枝1,给的字符串不满足切割有效的IP地址;2.剪枝2,分割实际只需要分割3个字符就行,缩小循环范围;3.每次切割后可以判断一下是否后面的字符还能够满足切割要求。

代码:

class Solution {
public://切割问题主要需要两点:切割,判断!//直接在字符串上进行操作,因此不设置路径数组vector<string> result; //返回数组//确定返回值和参数列表,直接在答案数组中插入因此不需要返回值,参数中需要原字符串s,分割点startindex//本题还需要一个int型变量point表示当前逗号的数量void backtracking(string& s, int startindex, int point) {//确定终止条件,当逗号数量为3个时,说明当前分割已经完成了if(point == 3) {//最后一部分字符串还需要进行判断if(ipvaild(s, startindex, s.size() - 1)) {result.push_back(s);}return;}//确定单层递归逻辑//剪枝2,分割只需要分割3个数字就够了for(int i = startindex; i < startindex + 3; i++) {//剪枝3,后续剩余的节点数不满足切割要求if(s.size() - startindex > (4 - point) * 3 || s.size() - startindex < (4 - point)) {break;}//startindex作为切割线,切割的字符串区间为[startindex, i],左闭右闭//判断切割下来的字符串是否合理if(ipvaild(s, startindex, i)){//如果合理的话,在字符串下标i后插入逗号,并进行下一轮递归s.insert(s.begin() + i + 1, '.');point++;//注意这里需要传入的是i+2,因为加了一个逗号,切割的位置需要往后移两位backtracking(s, i + 2, point);point--; //回溯s.erase(s.begin() + i + 1);}else {  //假如不满足,后续的切割方法也难以满足,直接跳出本层循环break;}}}bool ipvaild(string& s, int start, int end) {if (start > end) {return false;}//如果存在前置0的话,返回falseif(start != end && s[start] == '0') {return false;}int num = 0; //对切割字符串进行求和for(int i = start; i <= end; i++) {if(s[i] - '0' < 0 || s[i] - '0' > 9) {return false;}num = num * 10 + (s[i] - '0');if(num > 255) {return false;}}return true;}vector<string> restoreIpAddresses(string s) {//剪枝1,给的字符串不满足切割有效的ip地址if(s.size() < 4 || s.size() > 12) return result;backtracking(s, 0, 0);return result;}
};

78.子集

文档讲解:代码随想录子集

视频讲解:手撕子集问题

题目:

学习:回溯算法能够解决的第三类问题,子集问题。子集问题与切割问题和组合问题的本质不同在于,切割问题和组合问题都是在叶子节点收获结果,但是子集问题需要在每个节点都收获结果,这也导致了子集问题对result数组push_back的位置不同,但其他部分其实几乎是一致的。子集问题其实也能看作是一个组合问题,因此也需要注意去重。回溯逻辑转化为树形结构为:

代码:确定回溯三部曲

//时间复杂度O(n*2^n)
//空间复杂度O(n)
class Solution {
public:vector<vector<int>> result; //返回数组vector<int> path; //保存路径//确定返回值和参数列表,在数组中直接进行操作,所以不需要返回值,参数列表需要遍历的数组和当前遍历的下标void backtracking(vector<int>& nums, int startindex) {//子集问题的不同在于,子集收获答案是在每个节点均收货一次//在终止条件前,先进行收获,其中也包含了空集result.push_back(path);//确定终止条件(其实等于就可以了),遍历到最后//该终止条件也可以不写,因为当startindex >= nums.size()时,下面的for循环也不会进入,但要注意for循环后加return。if(startindex >= nums.size()) {return;}//确定单层递归逻辑for(int i = startindex; i < nums.size(); i++) {path.push_back(nums[i]);//传入i+1,防止出现重复backtracking(nums, i + 1);path.pop_back();}return;}vector<vector<int>> subsets(vector<int>& nums) {backtracking(nums, 0);return result;}
};

90.子集II

文档讲解:代码随想录子集II

视频讲解:手撕子集II

题目:

学习:本题和上一题不同点在于本题存在重复元素,需要对后续的相同元素进行去重,事实上本题和组合总和II的去重是相同的,本质都是如果后面出现了与前面相同的元素就可以跳过该元素的遍历,因为前面的元素一定把后面的元素还有的组合都包括的。基于此本题可以采取和40.组合总和II相同的去重方式,都是在树层进行去重

代码:确定回溯三部曲

//时间复杂度O(n*2^n)
//空间复杂度O(n)
class Solution {
public:  vector<vector<int>> result; //返回答案数组vector<int> path; //保存路径//确定参数和返回值void backtracking(vector<int>& nums, int startindex) {//收集每一个节点result.push_back(path);//确定终止条件if(startindex == nums.size()) {return;}//确定单层递归逻辑for(int i = startindex; i < nums.size(); i++) {//去重if(i > startindex && nums[i] == nums[i-1]){continue;}path.push_back(nums[i]);backtracking(nums, i + 1);path.pop_back();}return;}vector<vector<int>> subsetsWithDup(vector<int>& nums) {//进行排序,便于去重sort(nums.begin(), nums.end());backtracking(nums, 0);return result;}
};

总结 

切割问题首尾,子集问题开始,牢记子集问题和切割问题和组合问题的不同。

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

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

相关文章

安全架构概述_3.与信息安全相关的国内外标准及组织

1.国外标准 &#xff08;1&#xff09;可信计算机系统评估准则&#xff08;Trusted Computer System Evaluation Criteria&#xff0c;TCSEC&#xff09;&#xff0c;也称为“橘皮书”&#xff0c;1985年12月有美国国防部公布。 &#xff08;2&#xff09;信息技术安全评估准则…

如何利用python画出AHP-SWOT的战略四边形(四象限图)

在企业或产业发展的相关论文分析中&#xff0c;常用到AHP-SWOT法进行定量分析&#xff0c;形成判断矩阵后&#xff0c;如何构造整洁的战略四边形是分析的最后一个环节&#xff0c;本文现将相关代码发布如下&#xff1a; import mpl_toolkits.axisartist as axisartist import …

玩转springboot之springboot定制嵌入式的servlet

springboot定制嵌入式的servlet容器 修改容器配置 有两种方式可以修改容器的配置 可以直接在配置文件中修改和server有关的配置 server.port8081 server.tomcat.uri-encodingUTF-8//通用的Servlet容器设置 server.xxx //指定Tomcat的设置 server.tomcat.xxx编写一个EmbeddedSer…

5. web信息收集(OWASP实战训练)

5. web信息收集&#xff08;OWASP实战训练&#xff09; 1. 信息收集概述2. Google hacking2.1 Site2.2 filetype2.3 inurl2.4 intitle2.5 intext2.6 实例2.7 符号 3. shodan hacking3.1 IP3.2 service/protocol3.3 keyword3.4 country3.5 product3.6 version3.7 hostname3.8 os…

解决本机电脑只能通过localhost访问,不能通过127.0.0.1访问

背景问题 有天我启动项目&#xff0c;发现项目连接Mysq总是连接不上&#xff0c;查了url、ip、port、用户名和密码都没有错&#xff0c;就是连接不上mysql数据库&#xff0c;后来通过查找资料发现有多个进程占用3306端口。 pid 6016 是mysqld服务 而pid 9672 是一个叫 svchos…

windows终端

只要你和计算机有交互不妨来看看 什么是终端&#xff1f; 终端其实就是一个命令窗口。你可以用它向电脑和操作系统发出指令&#xff1a;比如创建文件&#xff0c;删除文件之类的。 为什么要用终端&#xff1f;&#xff08;终端得好处&#xff09; windows最开始的时候时没有…

逆变器--学习笔记(一)

并网&#xff1a; 逆变器中的“并网”指的是逆变器将其产生的交流电与电网同步&#xff0c;并输送到公共电网中。并网逆变器通常用于太阳能发电系统和其他分布式发电系统&#xff0c;将其产生的电能输送到电网供其他用户使用。 THD谐波失真总量: 逆变器的THD&#xff08;Tot…

大模型系列课程学习-基于2080TI-22G魔改卡搭建双卡大模型训练平台(双系统)

1.选择合适的硬件配置 再配置电脑之前&#xff0c;需要确认自己需要的显存大小、主板、内存条、电源、散热等核心配件。经过前期调研&#xff0c;选择的硬件配置如下&#xff1a; &#xff08;1&#xff09;主板&#xff1a;华南X99_F8D(DDR4主板)&#xff0c;因为需要支持双卡…

Python: PyCharm 2023.1 调试

1.设断点 &#xff08;行号对应的红色点&#xff0c;在需要设置断点的代码行与行号之间鼠标点击即可以设置&#xff09; 2.shiftF9,或 altshiftf9 选择文件 或是在菜单 Run->debug "main" 或是在菜单Run->debug 选择文件 &#xff08;鼠标光标放在设置第一个…

DDD学习笔记四

领域模型的构建 基础领域模型的基本组成有名称、属性、关联、职责、事件和异常 发掘领域概念3种策略&#xff1a; 1&#xff09;学习已有系统&#xff0c;重用已有模型 2&#xff09;使用分类标签。分类标签来源于领域&#xff0c;需要我们研究一些资料并做一些提炼。从采用5W…

深入解析scikit-learn中的交叉验证方法

交叉验证是机器学习中用于评估模型性能的重要技术&#xff0c;它可以帮助我们理解模型在未知数据上的泛化能力。scikit-learn&#xff08;简称sklearn&#xff09;是一个广泛使用的Python机器学习库&#xff0c;提供了多种交叉验证方法。本文将详细介绍scikit-learn中提供的交叉…

基于elastic stack的docker-compose部署的ELK与LDAP集成

说明&#xff1a; ldap信息配置到es配置文件上&#xff0c;然后kibana读取es的配置信息 用户与角色的关系通过role_mapping.yml文件配置获取 角色与权限的关系通过elastic stack提供的DevTools或API进行维护 一、前置条件&#xff1a; 1.1 es已开启xpack&#xff08;已开启…

centos误删yum和python

在下载pkdg时&#xff0c;因为yum报错坏的解释器&#xff0c;然后误删了yum和python。 在下载各种版本&#xff0c;创建各种软连接&#xff0c;修改yum文件都不好使后&#xff0c;发现了这样一个方法&#xff1a;Centos&#xff1a; 完美解决python升级导致的yum报错问题(相信…

DIY智能音箱:基于STM32的低成本解决方案 (附详细教程)

摘要: 本文详细介绍了基于STM32的智能音箱的设计与实现过程&#xff0c;包括硬件设计、软件架构、语音识别、音乐播放等关键技术。通过图文并茂的方式&#xff0c;结合Mermaid流程图和代码示例&#xff0c;帮助读者深入理解智能音箱的工作原理&#xff0c;并提供实际操作指导。…

《每天5分钟用Flask搭建一个管理系统》第9章:API设计

第9章&#xff1a;API设计 9.1 RESTful API的概念 RESTful API是一种基于HTTP协议的网络服务接口设计方法&#xff0c;它使用标准的HTTP方法&#xff0c;如GET、POST、PUT、DELETE等&#xff0c;来执行资源的操作。 9.2 Flask-RESTful扩展的使用 Flask-RESTful是一个Flask扩…

利用队列Queue或栈Stack解决字符数组转换运算题

一、题目 给定包含特殊运算符号&#xff0c;$ &#xff0c;转换规则如下 xy2xy3 x$y 3x2y1 其中x&#xff0c;y都是非负整数且优先级高于 $。 相同的特殊运算符&#xff0c;从左到右顺序计算。用例保证&#xff0c;$&#xff0c;左右一定存在数字&#xff0c;且数字不存在前导…

汇川CodeSysPLC教程03-2-10 如何组态

大家好&#xff0c;我是阿凡工控分享&#xff0c;本期我们将调整教程的顺序&#xff0c;和粉丝朋友们讨论后&#xff0c;后续我将优先出绿旗标注的部分&#xff0c;便于小白水平的你循序渐进&#xff0c;其他水平的朋友有些需求可能要稍后了&#xff0c;如果有问题请见谅&#…

Batch文件中的goto命令:控制流程的艺术

Batch文件&#xff0c;也称为批处理脚本&#xff0c;是Windows操作系统中用于自动化任务的一种脚本文件。在Batch脚本中&#xff0c;goto命令是一个至关重要的控制结构&#xff0c;它允许脚本跳转到指定的标签位置&#xff0c;从而实现循环、条件分支等复杂的控制流程。本文将详…

【Spring成神之路】一次SpringIOC源码之旅,女朋友也成为了Spring大神!

文章目录 一、前言二、前置准备三、IOC容器的使用四、Spring IOC源码解读1. prepareRefresh源码解读2. obtainFreshBeanFactory源码解读2.1 refreshBeanFactory源码解读 3. prepareBeanFactory源码解读4. postProcessBeanFactory源码解读5. invokeBeanFactoryPostProcessors源码…

Linux-C/C++开发环境常用软件安装

安装/升级 LLVM&#xff08;包含clang&#xff09; 安装/升级 GCC 安装/升级CMake 安装/升级 Python 升级Linux内核 安装/升级 OpenSSL