当前位置: 首页 > news >正文

不容易解的题10.10

5.最长回文子串

5. 最长回文子串 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/longest-palindromic-substring/?envType=list&envId=ZCa7r67M给一个字符串,让我们找最长回文子串

这题不用说,回文子串那一定是连续的,第一眼看可能想到滑窗,想法是好想法,但是你如何确定窗口大小?又如何确定窗口什么情况下左窗口怎么运动,又是什么情况右窗口运动呢?为了找全子串不落下答案,那我们应该从第一个位置开始左窗口,那么什么时候左窗口右移动呢?

这实际上就只能使用双for循环来确定此时子串开始终止位置了,然后判断该字串是否回文,如果回文看长度更新答案。没错最开始我就是这样想的,也是这样实现的,但是需要右剪枝,不然容易超时。

class Solution {
public:
bool fun(string&s,int left,int right){while(left<right){if(s[left++]!=s[right--])return false;}return true;
}string longestPalindrome(string s) {if(s.size()==0)return "";string res;res+=s[0];for(int i=0;i<s.size();i++){for(int j=i+1;j<s.size();j++){bool t=fun(s,i,j);if(t){string tmp=s.substr(i,j-i+1);res=tmp.size()>res.size()?tmp:res;}if(j+1==s.size()&&res.size()==j-i+1)return res;}}return res;}
};

剪枝就是如果当前右窗口已经遍历到整个s最后一个位置且res也等于该窗口大小
则直接return因为后面不可能存在更长的回文子串了

怎么样是不是还算有一点技巧,时间消耗非常多,大概200+,而且我也是超时后才想到这个剪枝的,更好的算法我在这里介绍两个,一个是中心探测,一个是马拉车(竞赛算法)。

中心探测是马拉车算法的雏形(基础),也就是说你不会中心探测写不出来马拉车算法,但我个人觉得中心探测就十分的好用了,它可以使时间消耗变得很小了,如果不是在特殊要求时间或性能的前提下,使用中心探测可以更好的更快速的不出错的书写代码。

思路:中心探测法要求以字符串的每个字符作为中心探测的中心点,开始向两边进行试探,判断两边的元素是否对应相等,这里有一个不太容易察觉的问题

一个字符串的长度奇偶性会影响判断的结果,如果长度为奇数那非常好办,以中点左右探测不会出现问题,但如果为偶数不容易确定取拿一个为中心点,我们使用填充字符串的技术,无论给定字符串长度奇偶性如何,都用字符填充使它变成奇数长度。

然后再去比较,代码如下

class Solution {
public:
int fun(const string& s,int left,int right){while(left>=0&&right<s.size()&&s[left]==s[right]){left--,++right;}return (right-left-2)/2;
}string longestPalindrome(string s) {string ss="#";int n=0;int start=0,maxn=0;for(char i:s){ss+=i;ss+='#';}for(int i=0;i<ss.size();++i){int n=fun(ss,i,i);if(maxn<n){maxn=n;start=(i-maxn)/2;}}return s.substr(start,maxn);}
};

这里我们使用#号填充,实际你用一个字符串里肯定不会出现的字符填充就可以不一定非要#。

判断回文和更新答案这里我说一下,直接看可能看不懂。

我们由于扩大了字符串用井号,而且是相当于每个原本字符的左右两边各含有一个#(注:原版是在最后一个字符填写完之后,还要有一个#填充,这里我发现少写一个也能通过),这相当于原本的字符下标扩大1倍,我们使用函数fun来返回当前以该字符为中心回文子串长度,返回结果时候需要-2这是因为left--,right++后我们发现的不回文,返回答案,所以实际应该取的答案比这小2,再就是/2,为什么除2,因为我们的得到的长度是扩大1倍下标的长度/2才是源字符串回文长度

解释完了这个解释里面的更新数据,maxn更新一目了然,然后是start这个是代表源字符串从哪个字符起取回文子串,是当前下标减去回文半径,因为是中心探测法,寻找的回文串,所以当前下标代表的是回文串中心而不是起始位置,所以是减法,然后这里的/2是因为#填充下标扩大1倍,所以/2。然后最后以start为开始,截取长度为maxn。

manacher算法:

class Solution {
public:string longestPalindrome(string s) {string tmp="#";for(char c:s){tmp+=c;tmp+='#';}tmp+='#';vector<int>arr(tmp.size(),0);int start=0,max=0,right=0,center=0;for(int i=0;i<tmp.size();++i){if(i<=right){int minarmlen=min(right-i,arr[2*center-i]);arr[i]=fun(tmp,i-minarmlen,i+minarmlen);}else arr[i]=fun(tmp,i,i);if(arr[i]>max){max=arr[i];start=(i-max)/2;           }if(i+arr[i]>right){center=i;right=i+arr[i];}}return s.substr(start,max);}
private:int fun(string&s,int left,int right){while(left>=0&&right<s.size()&&s[left]==s[right]){--left,++right;}return (right-left-2)/2;}
};

根据代码看讲解:

优化思路:使用一个数组来记录每个位置的以该位置为中心回文子串的最大长度
由于回文串的对称性我们可以找到以center为中心对称的那个位置
而center是随着i不断增大,且只会出现在i的左侧或和i相等
所以当前i的对称位置一定存在,我们根据镜像的那个i位置去查表,即可得知它可以向外扩张几个字符(取决于镜像位置为中心的回文串有多长)
什么时候可以依赖于查表确定跳过几个字符什么时候不可以?
跳过字符的原因是对称位置由于记录了以它为中心最长字串长度,所以遍历到i时如果可以以center为中心找到对称位置,且此时i在以center为中心的最远半径内,即可完成跳转。
即i<=right,我们取i+镜像表最长回文长度与right-i长度取最小,来完成此时的跳跃

跳跃是什么意思?就是left往前越过right往后越过一些字符,这些字符必定回文,不需要再做判断
如果i>center则不能跳跃,因为此时已经不在可预测范围内,center为中心的最长可预测范围就到right,因为最长回文子串以center中心最长到right
center如何确定?
我们往后遍历i在某时出现最长回文子串长度大于当前存储的长度时,把center移到i位置,且以该长度确定right即,当前right最远达哪里。

该思路是我自己总结较为简短的主要注意点,如果不明白可以看看更为完全的解析,我这里只把我认为最重要的几点讲明理解。

 这种思路就是用到回文镜像对称,以已知范围去减少判断回文次数,其他的代码实现就是中心探测法,练多了就明白了。


本期文章只有一道题,因为我发现更新三四道详解的题目会使得篇幅过长,阅读量过低,我试试只更新一道题会不会有所改变。

都看到这里了如果对您有用的话别忘了一键三连哦,如果是互粉回访我也会做的!

大家有什么想看的题解,或者想看的算法专栏、数据结构专栏,可以去看看往期的文章,有想看的新题目或者专栏也可以评论区写出来,讨论一番,本账号将持续更新。
期待您的关注

相关文章:

不容易解的题10.10

5.最长回文子串 5. 最长回文子串 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/longest-palindromic-substring/?envTypelist&envIdZCa7r67M给一个字符串&#xff0c;让我们找最长回文子串 这题不用说&#xff0c;回文子串那一定是连续的&#…...

淘宝天猫店铺所有商品数据接口,淘宝API接口

获取淘宝店铺所有商品数据接口的步骤如下&#xff1a; 获取授权&#xff1a;使用 OAuth 2.0 协议对应用进行授权&#xff0c;以便能够访问店铺的商品信息。获取店铺信息&#xff1a;使用淘宝 API 的 taobao.shop.get 接口&#xff0c;传入店铺的 user_id 参数&#xff0c;获取…...

Prometheus和grafana安装配置手册

1.简介 本文档为prometheus和grafana安装配置手册&#xff0c;prometheus和grafana的内容、和操作过程&#xff0c;详细介绍了服务监控配置、dashboard配置、告警配置等操作。 2.部署说明 Prometheus基于Golang编写&#xff08;需要安装&#xff09;&#xff0c;编译后的软件…...

从零开始探索C语言(十一)----共用体和位域

文章目录 1. 共用体1.1 定义共用体1.2 访问共用体成员 2. 位域2.1 位域声明2.2 位域的定义和位域变量的说明2.3 位域的使用2.4 位域小结 1. 共用体 共用体是一种特殊的数据类型&#xff0c;允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体&#…...

【数据结构】算法的时间复杂度

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 一.算法时间复杂度定义 二.大O阶渐近表示法 &#x1f38f;大O阶渐近表示法的定义 &#x1f38f;推导大O阶方法 三.常见的时间复杂度 &#x1f4cc;常数阶 &#x…...

Qt作业五

1、思维导图 https://www.zhixi.com/view/9e899ee0 2、作业 #include <iostream>using namespace std;class Animal { private:string name; public:Animal(){}Animal(string n):name(n){}virtual void perform()0; };class Lion:public Animal { public:void perform…...

【面试】pc寄存器题

目录 1.使用pc寄存器存储字节码指令地址有什么作用&#xff1f;&#xff08;为什么使用pc寄存器记录当前线程的执行地址&#xff1f;&#xff09;2.pc寄存器为什么被设定为线程私有的&#xff1f; 1.使用pc寄存器存储字节码指令地址有什么作用&#xff1f;&#xff08;为什么使…...

ARM按键中断实验

设置按键中断&#xff0c;按键1按下&#xff0c;LED亮&#xff0c;再按一次&#xff0c;灭 按键2按下&#xff0c;蜂鸣器响。再按一次&#xff0c;不响 按键3按下&#xff0c;风扇转&#xff0c;再按一次&#xff0c;风扇停 src/do_irq.c #include "key_it.h" ex…...

C#的值类型和引用类型

不得不说c#的类型系统设计有点意思&#xff0c;不同的编程语言对于类型的设计各有取舍。 值类型&#xff1a; 当我们将一个int类型的值赋值到另一个int类型的值时&#xff0c;它实际上是创建了一个完全不同的副本。换句话说&#xff0c;如果你改变了其中某一个的值&#xff0…...

YOLOv7改进:极简的神经网络模型 VanillaNet---VanillaBlock助力检测,实现暴力涨点 | 华为诺亚2023

💡💡💡本文属于原创独家改进:极简模块VanillaBlock,以极简主义的设计为理念,网络中仅仅包含最简单的卷积计算,去掉了残差和注意力模块,二次创新引入到YOLOv7中取得了不俗的效果。 极简模块VanillaBlock | 亲测在多个数据集实现涨点; 收录: YOLOv7高阶自研专…...

对验证码的识别爆破

声明&#xff1a;该系列文章首发于公众号&#xff1a;Y1X1n安全&#xff0c;转载请注明出处&#xff01;本公众号所分享内容仅用于每一个爱好者之间的技术讨论及教育目的&#xff0c;所有渗透及工具的使用都需获取授权&#xff0c;禁止用于违法途径&#xff0c;否则需自行承担&…...

LeetCode【15】三数之和

题目&#xff1a; 解析&#xff1a; 参考&#xff1a;https://zhuanlan.zhihu.com/p/111715985 代码&#xff1a; public static List<List<Integer>> threeSum(int[] nums) {// 先排序Arrays.sort(nums);List<List<Integer>> result new ArrayLis…...

Gossip协议是什么

Gossip协议是什么 Gossip protocol 也叫 Epidemic Protocol (流行病协议), 是基于流行病传播方式的节点或者进程之间信息交换的协议, 也被叫做流言算法, 八卦算法、疫情传播算法等等. 说到 Gossip 协议, 就不得不提著名的六度分隔理论. 简单地说, 你和任何一个陌生人之间所间…...

【java学习】this关键字(27)

文章目录 1. this是什么&#xff1f;2. this的作用 1. this是什么&#xff1f; 在 java 中&#xff0c;this关键字比较难理解&#xff0c;它的作用和其词义很接近。 ①它在方法内部使用&#xff0c;即这个方法所属对象的引用&#xff1b; ②它在构造器内部使用&#xff0c;表示…...

27、元组

区分&#xff1a; 数组&#xff1a;纯粹 一个[]中的数据类型都是一致的 元组&#xff1a;不纯粹 一个[]中可能有不同类型的数据项 意义 当赋值或访问一个已知索引的元素时&#xff0c;可以得到正确的类型 let miao: [string, number] [cat, 18]; miao[0] cat miao[1] 18…...

1km分辨率逐月降雨量和最高温度数据集(1901-2022)--数据处理

1km分辨率逐月降雨量和最高温度数据集&#xff08;1901-2022&#xff09;的下载可以参考我的另外一篇博客&#xff1a; 这里的温度和降雨数据集都是NC格式的&#xff0c;需要将其处理为tif格式&#xff0c;我采用的处理软件是MATLAB。 本篇博客以处理温度数据为例&#xff0c…...

docker入门加实战—docker常见命令

docker入门加实战—docker常见命令 在介绍命令之前&#xff0c;先用一副图形象的展示一下docker的命令&#xff1a; 常见命令 docker的常见命令和文档地址如下表&#xff1a; 命令说明文档地址docker pull拉取镜像docker pulldocker push推送镜像到DockerRegistrydocker pus…...

【C/C++】使用 g++ 编译器编译 C++ 程序的完全指南

本文介绍了 g 编译器的使用方法和常见参数解释&#xff0c;帮助您编译和构建 C 程序。 引言 在 C 程序开发中&#xff0c;选择一个合适的编译器是至关重要的。g 是 GNU 编译器集合&#xff08;GCC&#xff09;中的 C 编译器&#xff0c;提供了丰富的功能和选项&#xff0c;帮…...

ARM中断实验

设置按键中断&#xff0c;按键1按下&#xff0c;LED亮&#xff0c;再按一次&#xff0c;灭 按键2按下&#xff0c;蜂鸣器响。再按一次&#xff0c;不响 按键3按下&#xff0c;风扇转&#xff0c;再按一次&#xff0c;风扇停 main.c #include "uart1.h" #include …...

Vue条件渲染

一、使用v-show条件渲染 语法格式&#xff1a; v-show"表达式" // true 或 false 当表达式的值为true的时候就显示&#xff0c;表达式值为false的时候隐藏。 下面是使用v-show实现的一个点击按钮切换显示和隐藏的小案例 &#xff1a; 值得注意的是&#xff0c;使…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”

非常好&#xff0c;我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题&#xff0c;统一使用 二重复合函数&#xff1a; z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y))​ 来全面说明。我们会展示其全微分形式&#xff08;偏导…...

rm视觉学习1-自瞄部分

首先先感谢中南大学的开源&#xff0c;提供了很全面的思路&#xff0c;减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接&#xff1a;https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架&#xff1a; 代码框架结构&#xff1a;readme有…...