不容易解的题10.10
5.最长回文子串
5. 最长回文子串 - 力扣(LeetCode)
https://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. 最长回文子串 - 力扣(LeetCode)https://leetcode.cn/problems/longest-palindromic-substring/?envTypelist&envIdZCa7r67M给一个字符串,让我们找最长回文子串 这题不用说,回文子串那一定是连续的&#…...
淘宝天猫店铺所有商品数据接口,淘宝API接口
获取淘宝店铺所有商品数据接口的步骤如下: 获取授权:使用 OAuth 2.0 协议对应用进行授权,以便能够访问店铺的商品信息。获取店铺信息:使用淘宝 API 的 taobao.shop.get 接口,传入店铺的 user_id 参数,获取…...
Prometheus和grafana安装配置手册
1.简介 本文档为prometheus和grafana安装配置手册,prometheus和grafana的内容、和操作过程,详细介绍了服务监控配置、dashboard配置、告警配置等操作。 2.部署说明 Prometheus基于Golang编写(需要安装),编译后的软件…...
从零开始探索C语言(十一)----共用体和位域
文章目录 1. 共用体1.1 定义共用体1.2 访问共用体成员 2. 位域2.1 位域声明2.2 位域的定义和位域变量的说明2.3 位域的使用2.4 位域小结 1. 共用体 共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体&#…...
【数据结构】算法的时间复杂度
🦄个人主页:修修修也 🎏所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 一.算法时间复杂度定义 二.大O阶渐近表示法 🎏大O阶渐近表示法的定义 🎏推导大O阶方法 三.常见的时间复杂度 📌常数阶 &#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寄存器存储字节码指令地址有什么作用?(为什么使用pc寄存器记录当前线程的执行地址?)2.pc寄存器为什么被设定为线程私有的? 1.使用pc寄存器存储字节码指令地址有什么作用?(为什么使…...
ARM按键中断实验
设置按键中断,按键1按下,LED亮,再按一次,灭 按键2按下,蜂鸣器响。再按一次,不响 按键3按下,风扇转,再按一次,风扇停 src/do_irq.c #include "key_it.h" ex…...
C#的值类型和引用类型
不得不说c#的类型系统设计有点意思,不同的编程语言对于类型的设计各有取舍。 值类型: 当我们将一个int类型的值赋值到另一个int类型的值时,它实际上是创建了一个完全不同的副本。换句话说,如果你改变了其中某一个的值࿰…...
YOLOv7改进:极简的神经网络模型 VanillaNet---VanillaBlock助力检测,实现暴力涨点 | 华为诺亚2023
💡💡💡本文属于原创独家改进:极简模块VanillaBlock,以极简主义的设计为理念,网络中仅仅包含最简单的卷积计算,去掉了残差和注意力模块,二次创新引入到YOLOv7中取得了不俗的效果。 极简模块VanillaBlock | 亲测在多个数据集实现涨点; 收录: YOLOv7高阶自研专…...
对验证码的识别爆破
声明:该系列文章首发于公众号:Y1X1n安全,转载请注明出处!本公众号所分享内容仅用于每一个爱好者之间的技术讨论及教育目的,所有渗透及工具的使用都需获取授权,禁止用于违法途径,否则需自行承担&…...
LeetCode【15】三数之和
题目: 解析: 参考:https://zhuanlan.zhihu.com/p/111715985 代码: 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是什么?2. this的作用 1. this是什么? 在 java 中,this关键字比较难理解,它的作用和其词义很接近。 ①它在方法内部使用,即这个方法所属对象的引用; ②它在构造器内部使用,表示…...
27、元组
区分: 数组:纯粹 一个[]中的数据类型都是一致的 元组:不纯粹 一个[]中可能有不同类型的数据项 意义 当赋值或访问一个已知索引的元素时,可以得到正确的类型 let miao: [string, number] [cat, 18]; miao[0] cat miao[1] 18…...
1km分辨率逐月降雨量和最高温度数据集(1901-2022)--数据处理
1km分辨率逐月降雨量和最高温度数据集(1901-2022)的下载可以参考我的另外一篇博客: 这里的温度和降雨数据集都是NC格式的,需要将其处理为tif格式,我采用的处理软件是MATLAB。 本篇博客以处理温度数据为例,…...
docker入门加实战—docker常见命令
docker入门加实战—docker常见命令 在介绍命令之前,先用一副图形象的展示一下docker的命令: 常见命令 docker的常见命令和文档地址如下表: 命令说明文档地址docker pull拉取镜像docker pulldocker push推送镜像到DockerRegistrydocker pus…...
【C/C++】使用 g++ 编译器编译 C++ 程序的完全指南
本文介绍了 g 编译器的使用方法和常见参数解释,帮助您编译和构建 C 程序。 引言 在 C 程序开发中,选择一个合适的编译器是至关重要的。g 是 GNU 编译器集合(GCC)中的 C 编译器,提供了丰富的功能和选项,帮…...
ARM中断实验
设置按键中断,按键1按下,LED亮,再按一次,灭 按键2按下,蜂鸣器响。再按一次,不响 按键3按下,风扇转,再按一次,风扇停 main.c #include "uart1.h" #include …...
Vue条件渲染
一、使用v-show条件渲染 语法格式: v-show"表达式" // true 或 false 当表达式的值为true的时候就显示,表达式值为false的时候隐藏。 下面是使用v-show实现的一个点击按钮切换显示和隐藏的小案例 : 值得注意的是,使…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
