代码随想录训练营day28

第七章 回溯算法part04

1.LeetCode.复原IP地址

1.1题目链接:93.复原IP地址

文章讲解:代码随想录
视频讲解:B站卡哥视频

1.2思路:其实只要意识到这是切割问题,切割问题就可以使用回溯搜索法把所有可能性搜出来,和刚做过的131.分割回文串就十分类似了。

切割问题可以抽象为树型结构,如图:
在这里插入图片描述
单层搜索的逻辑
在131.分割回文串 (opens new window)中已经讲过在循环遍历中如何截取子串。
在for (int i = startIndex; i < s.size(); i++)循环中 [startIndex, i] 这个区间就是截取的子串,需要判断这个子串是否合法。
如果合法就在字符串后面加上符号.表示已经分割。
如果不合法就结束本层循环,如图中剪掉的分支:
在这里插入图片描述

然后就是递归和回溯的过程:
递归调用时,下一层递归的startIndex要从i+2开始(因为需要在字符串中加入了分隔符.),同时记录分割符的数量pointNum 要 +1。
回溯的时候,就将刚刚加入的分隔符. 删掉就可以了,pointNum也要-1。

1.3附加代码如下所示:

class Solution {
public:vector<string>result;// startIndex: 搜索的起始位置,pointNum:添加逗点的数量void backtracking(string &s,int startindex,int pointsum)//这里不能采用const string了因为要在原来字符上进行更改了{if(pointsum==3)// 逗点数量为3时,分隔结束{// 判断第四段子字符串是否合法,如果合法就放进result中if(iSvalid(s,startindex,s.size()-1))//检查最后一个整数是否符合要求{result.push_back(s);return;}}for(int i=startindex;i<s.size();i++){if(iSvalid(s,startindex,i))// 判断 [startIndex,i] 这个区间的子串是否合法{s.insert(s.begin()+i+1,'.');pointsum++;backtracking(s,i+2,pointsum);// 插入逗点之后下一个子串的起始位置为i+2pointsum--;//回溯s.erase(s.begin()+i+1);// 回溯删掉逗点}else {break; // 不合法,直接结束本层循环}}}// 判断字符串s在左闭又闭区间[start, end]所组成的数字是否合法bool iSvalid(const string &s,int begin,int end){if(begin>end)return false;if(end-begin>0&&s[begin]=='0')return false;if(end-begin>=3)return false;if(end-begin>0&&end-begin<3){string str=s.substr(begin,end-begin+1);int num=stoi(str);if(num>255)return false;}return true;}// //法2 判断是否有效// bool isValid(const string& s, int start, int end) {//     if (start > end) {//         return false;//     }//     if (s[start] == '0' && start != end) { // 0开头的数字不合法//             return false;//     }//     int num = 0;//     for (int i = start; i <= end; i++) {//         if (s[i] > '9' || s[i] < '0') { // 遇到非数字字符不合法//             return false;//         }//         num = num * 10 + (s[i] - '0');//         if (num > 255) { // 如果大于255了不合法//             return false;//         }//     }//     return true;// }vector<string> restoreIpAddresses(string s) {result.clear();backtracking(s,0,0);return result;}
};

2.LeetCode. 子集

2.1题目链接:78.子集

文章讲解:代码随想录
视频讲解:B站卡哥视频

2.2思路:如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点!

其实子集也是一种组合问题,因为它的集合是无序的,子集{1,2} 和 子集{2,1}是一样的。
那么既然是无序,取过的元素不会重复取,写回溯算法的时候,for就要从startIndex开始,而不是从0开始!
有同学问了,什么时候for可以从0开始呢?
求排列问题的时候,就要从0开始,因为集合是有序的,{1, 2} 和{2, 1}是两个集合,排列问题我们后续的文章就会讲到的。
以示例中nums = [1,2,3]为例把求子集抽象为树型结构,如下:
在这里插入图片描述
从图中红线部分,可以看出遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合。

2.3附加代码如下所示:

//法1
class Solution {
public:vector<vector<int>>result;vector<int>path;void backtracking(vector<int>&nums,int startindex){if(startindex>=nums.size())return;// 终止条件可以不加,因为for循环会起到终止作用for(int i=startindex;i<nums.size();i++){path.push_back(nums[i]);result.push_back(path);//在这里进行添加的话会漏掉空集的情况,需要单独处理添加空集,遍历到每一个节点都要进行保存backtracking(nums,i+1);path.pop_back();}return;}vector<vector<int>> subsets(vector<int>& nums) {path.clear();result.clear();result.push_back({});backtracking(nums,0);return result;}
};
//法2
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++){path.push_back(nums[i]);backtracking(nums,i+1);path.pop_back();}return;}vector<vector<int>> subsets(vector<int>& nums) {path.clear();result.clear();backtracking(nums,0);return result;}
};

3.LeetCode.子集II

3.1题目链接:90.子集II

文章讲解:代码随想录
视频讲解:B站卡哥视频

3.2思路:这道题目和78.子集 区别就是集合里有重复元素了,而且求取的子集要去重。

那么关于回溯算法中的去重问题,在40.组合总和II (opens new window)中已经详细讲解过了,和本题是一个套路。
剧透一下,后期要讲解的排列问题里去重也是这个套路,所以理解“树层去重”和“树枝去重”非常重要。
用示例中的[1, 2, 2] 来举例,如图所示: (注意去重需要先对集合排序)
在这里插入图片描述从图中可以看出,同一树层上重复取2 就要过滤掉,同一树枝上就可以重复取2,因为同一树枝上元素的集合才是唯一子集!
本题就是其实就是回溯算法:求子集问题! (opens new window)的基础上加上了去重,

3.3附加代码如下所示:

//法1
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();}}vector<vector<int>> subsetsWithDup(vector<int>& nums) {//首先要对数组进行排序方便去重sort(nums.begin(),nums.end());result.clear();path.clear();backtracking(nums,0);return result;}
};
//法2
//区分出树层去重和树枝去重的区别,只要进行树层去重即可
class Solution {
public:vector<vector<int>>result;vector<int>path;void backtracking(vector<int>&nums,int startindex,vector<bool>&used){result.push_back(path);if(startindex>=nums.size())return;for(int i=startindex;i<nums.size();i++){if(i>0&&nums[i]==nums[i-1]&&used[i-1]==false){continue;}path.push_back(nums[i]);used[i]=true;backtracking(nums,i+1,used);used[i]=false;path.pop_back();}}vector<vector<int>> subsetsWithDup(vector<int>& nums) {//首先要对数组进行排序方便去重sort(nums.begin(),nums.end());result.clear();path.clear();vector<bool>used(nums.size(),false);backtracking(nums,0,used);return result;}
};

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

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

相关文章

Web3 游戏周报(3.24-3.30)

【3.24-3.30】Web3 游戏行业动态&#xff1a; Web3 开发平台 Mirror World 在 Solana 上推出首个游戏 rollup 链 NFT 卡牌游戏 Parallel 完成 3,500 万美元融资&#xff0c;Solana Ventures 等参投 加密游戏开发公司 Gunzilla Games 完成 3,000 万美元融资 Telegram 游戏 No…

Linux环境基础和工具的使用

目录 1、Linux软件包管理器---yum 2、Linux开发工具 2.1、vim基本概念 2.2 vim基本操作 2.3 vim正常模式命令集 2.4 vim末行模式命令集 2.5 简单vim配置 2.5.1 配置文件的位置 3 Linux编译器--gcc/g的使用 3.1 背景知识 3.2 gcc完成 4 Linux调试器--gdb使用 4.1 背…

RK3568驱动指南|第十四篇 单总线-第158章DS18B20编写字符设备驱动框架

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

站群CMS系统

站群CMS系统是一种用于批量建立和管理网站的内容管理系统&#xff0c;它能够帮助用户快速创建大量的网站&#xff0c;并实现对这些网站的集中管理。以下是三个在使用广泛的站群CMS系统&#xff0c;它们各具特色&#xff0c;可以满足不同用户的需求。 1. Z-BlogPHP Z-BlogPHP是…

深入解析大数据体系中的ETL工作原理及常见组件

** 引言 关联阅读博客文章&#xff1a;探讨在大数据体系中API的通信机制与工作原理 关联阅读博客文章&#xff1a;深入理解HDFS工作原理&#xff1a;大数据存储和容错性机制解析 ** 在当今数字化时代&#xff0c;大数据处理已经成为了企业成功的重要组成部分。而在大数据处…

mybatis流式游标查询-导出DB大数据量查询OOM问题

问题场景 Mysql数据处理类型分以下三种 com.mysql.cj.protocol.a.result.ResultsetRowsStatic&#xff1a;普通查询&#xff0c;将结果集一次性全部拉取到内存 com.mysql.cj.protocol.a.result.ResultsetRowsCursor&#xff1a;游标查询&#xff0c;将结果集分批拉取到内存&…

基于kmeans的聚类微博舆情分析系统

第一章绪论 1.1研究背景 如今在我们的生活与生产的每个角落都可以见到数据与信息的身影。自从上十世纪八十年代的中后期开始&#xff0c;我们使用的互联网技术已经开始快速发展&#xff0c;近些年来云计算、大数据和物联网等与互联网有相领域的发展让互联网技术达到了史无前例…

ChatGPT解决hmm...something seems to have gone wrong.

ChatGPT解决hmm…something seems to have gone wrong. 这里是官方社区的一种workaround办法。仅仅只是mark一下。 我这边遇到的现象是&#xff0c;ChatGPT 3.5是正常的&#xff0c;但是使用ChatGPT 4就会频繁的出现这样的输出。而且恶心的是&#xff0c;即使是这种输出&…

BUCK、BOOST、BUCK-BOOST电路原理分析

一、前导 DC-DC DC-DC电源&#xff0c;即直流-直流变换器&#xff0c;是指将一个固定的直流电压变换为可变的直流电压&#xff0c;也称为直流斩波器。DC-DC有多种拓扑结构&#xff0c;如BUCK&#xff08;降压&#xff09;、BOOST&#xff08;升压&#xff09;、BUCK-BOOST&…

php反序列化漏洞——phar反序列化漏洞

一.什么是phar文件 类比java语言 JAR是开发Java程序一个应用&#xff0c;包括所有的可执行、可访问的文件&#xff0c;都打包进了一个JAR文件里使得部署过程十分简单。 PHAR("Php ARchive")是PHP里类似于JAR的一种打包文件 对于PHP 5.3 或更高版本&#xff0c;Ph…

软件设计师26--关系代数

软件设计师26--关系代数 考点1&#xff1a;关系模式相关概念例题&#xff1a; 考点1&#xff1a;关系模式相关概念 并∪&#xff1a;结果是两张表所有记录的合并&#xff0c;相同记录只显示一次。 交∩&#xff1a;结果是两张表中相同的记录。 差-&#xff1a;S1-S2&#xff0…

springboot+vue学生宿舍物品存放系统tnozt

需求包括&#xff1a; 三个角色&#xff1a;学生&#xff0c;公寓管理员&#xff08;宿舍管理人员&#xff09;&#xff0c;系统管理员。 本系统基于java语言&#xff0c;结合数据库技术&#xff0c;通过面向对象的设计方法&#xff0c;实现学生信息管理、公寓信息管理、物品存…

SWM341系列应用(USB应用)

1、测SWM341的主机功能&#xff0c;需要注意&#xff1a; SWM341的Host功能只支持Full Speed通信&#xff0c;好多U盘和tf读卡器都只支持High Speed&#xff0c;341无法与之通信 另外&#xff0c;测SWM341 Host的HID_Mouse例程时&#xff0c;好多鼠标都是Low Speed的&#xf…

C++ 标准库类型List

C/C总述&#xff1a;Study C/C-CSDN博客 目录 定义和初始化list对象 list中元素的访问 list的大小与容量 list的增 list的删 list的改 list的模拟实现 C 标准库中的 list 是一种双向链表容器&#xff0c;它支持快速的插入和删除操作。 ​ list 容器中各个元素的前后…

C++中的面向对象到底是什么

C中的面向对象到底是什么 对象嘛&#xff0c;就和大家都有的对象一样&#xff0c;两只眼睛、一个嘴巴、两条腿…… 对不起跑题了&#xff0c;C的面向对象中的对象可不是显示中的对象哦&#xff0c;但是有一些相似之处&#xff0c;有对象的同学可以参考着去学习C面向对象的概念…

AdaBoost算法详解自用笔记(1)二分类问题举例分析

AdaBoost算法详解自用笔记&#xff08;1&#xff09;二分类问题举例分析 提升方法的思路 AdaBoost作为一种提升方法&#xff0c;其需要回答两个问题&#xff1a;一是每一轮如何改变训练数据的权重或概率分布&#xff1b;二是如何将弱分类器组合成一个强分类器。对于第一个问题…

⾃定义类型:联合和枚举

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 点击主页&#xff1a;optimistic_chen和专栏&#xff1a;c语言&#xff0c; 创作不易&#xff0c;大佬们点赞鼓…

6.java openCV4.x 入门-Mat之局部区域读写及Range和Rect介绍

专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天建议把本文当作笔记来看&#xff0c;据说专栏目录里面有相应视频&#x1f92b; &#x1f9ed;文…

数据结构:非比较排序

非比较排序都具有很大的局限性,包括技术排序,基数排序,桶排序等 计数排序 时间复杂度:O(N) 空间复杂度:O(range) 适用范围 数据的范围集中的数组进行排序,不适合数据分散的数组 方法 统计每个数据出现的次数为n 建立一个相同大小的数组,将每个数据都初始化为0 然后遍历…

混合现实(MR)开发工具

混合现实&#xff08;MR&#xff09;开发工具是一系列软件和框架&#xff0c;它们使得开发者能够创建和优化能够在虚拟与现实世界之间无缝交互的应用程序。以下是一些在MR领域内广泛使用的开发工具。 1.Microsoft Mixed Reality Toolkit (MRTK) MRTK是一个跨平台的工具包&…