C++——Manacher算法
简介
Manacher算法用法较为单一,用于字符串求最长回文序列的长度,时间复杂度为线性复杂度O(n),n为添加了特殊字符的字符串的长度
思路
省略字符串预处理。直接开始介绍Len数组,关于字符串预处理的原因参见最下面的参考博客。
Len数组的用处
原字符串为S,处理后字符串为pro_str,用一个辅助数组Len[i]表示以字符T[i]为中心的最长回文字串的半径。如字符串abcdcd,则第一个d的Len值为2。Len[i]-1就是以S[i]为中心的回文子串的长度。即只要求出Len数组,就可以利用上述关系得到最长回文序列的长度。
如何计算Len数组
从左往右依次计算Len
,当计算Len[i]
时,Len[j](0<=j<i)
已经计算完毕。设pos
为之前计算中最长回文子串的中心下标,maxRight
为最长回文子串最右端字符的下标,分两种情况:
第一种情况:i<=maxRight
,找到i相对于pos
的对称位置,设为j
。此情况又分为两种子情况:Len[j]<maxRight-i
,Len[j]>=maxRight-i
。第一种子情况Len[j]<maxRight-i
说明以j
为中心的回文串一定在以pos
为中心的回文串的内部,且j
和i
关于位置pos
对称,所以以i
为中心的回文串的长度和以j
为中心的回文串一样,即Len[i]=Len[j]
。第二种子情况Len[j]>=maxRight-i
说明以i
为中心的回文串可能会延伸到maxRight
之外,但根据对称性,回文半径至少为maxRight-i
,而大于maxRight
的部分我们还没有进行匹配,所以要先置Len[i]=maxRight-i
,然后从maxRight+1
位置开始一个一个进行匹配,直到发生失配,从而更新maxRight
和对应的pos
以及Len[i]
。综上,这种情况先置Len[i]=min(len[2*pos-1],maxRight-i)
,然后再进行匹配,并更新maxRight
和对应的pos
。
第二种情况:i>maxRight
,如果i
比maxRight
还要大,说明对于中点为i
的回文串还一点都没有匹配,直接置Len[i]=1
这个时候,就只能老老实实地一个一个匹配了,匹配完成后要更新maxRight
的位置和对应的pos
以及Len[i]
。综上,这种情况先置Len[i]=1
,然后再进行匹配,并更新maxRight
和对应的pos
。
代码
#include<iostream>
#include<algorithm>
using namespace std;
string pro_str="";
//在字符串中间插入特殊字符
void preprocess(string s){for(int i=0;i<s.length();i++)pro_str=pro_str+"#"+s[i];pro_str+="#";
}
//manacher算法
void manachaer(string s){int len[s.length()]={0},pos=0,maxRight=0,maxLen=0;for(int i=0;i<s();i++){if(i<maxRight) len[i]=min(len[2*pos-1],maxRight-i);//第一种情况else len[i]=1; //第二种情况//进行匹配while(i+len[i]<s.length()&&i-len[i]>=0&&s[i+len[i]]==s[i-len[i]])len[i]++;//更新pos与maxRightif(i+len[i]-1>maxRight){maxRight=i+len[i]-1;pos=i;}maxLen=max(maxLen,len[i]);}cout<<maxLen-1;
}
int main(){string s;cin>>s;preprocess(s);manachaer(pro_str);return 0;
}
参考
文章一(CSDN)、文章二(简书)
C++——Manacher算法相关推荐
- manacher算法----O(n)最长回文串
manacher算法----O(n)最长回文串 分类:字符串 (126) (0) 举报 收藏 manacher的时间复杂度为O(n),后缀数组好像可以处理O(nlogn),但是有些变态题目可能卡 ...
- 谈谈我对Manacher算法的理解
Manacher算法其实是求字符串里面最长的回文. ①在学习该算法前,我们应该知道回文的定义:顺序读取回文和逆序读取回文得到的结果是一样的,如:abba,aba. 那么我们不难想到,在判断一个字符串s ...
- 【字符串】manacher算法
Definition 定义一个回文串为从字符串两侧向中心扫描时,左右指针指向得字符始终相同的字符串. 使用manacher算法可以在线性时间内求解出一个字符串的最长回文子串. Solution 考虑回 ...
- Manacher算法 , 实例 详解 . NYOJ 最长回文
51 Nod http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1089 Manacher 算法 定义数组 p[i]表示以i为 ...
- (回文串)Manacher算法
(回文串)Manacher算法 标签: ACM 回文串 Manacher 问题描述: 输入一个字符串,求出其中最大的回文子串.子串的含义是:在原串中连续出现的字符串片段.回文的含义是:正着看和倒着看相 ...
- 通俗易懂的最长回文串图解、说明及Java代码(中心扩散法和Manacher算法)
1. 回文串 作为程序员,回文串这个词已经见怪不怪了,就是一个字符串正着读和反着读是一样的,形式如abcdcba.bbaabb.这里涉及到奇回文和偶回文,奇回文指回文串的字符数是奇数,偶回文指回文串的 ...
- hdu 3068 最长回文(manacher算法)
最长回文 Time Limit: 4000/2000 M ...
- Manacher 算法模板
简介 在字符串的题目中,有时会遇上 回文串 这样一个名词 顾名思义,回文串 就是 正读和反读都一样的字符串 而 最长回文子串 ,就是在一个字符串的所有子串中,是回文串且长度最长的那个 求最长回文子串最 ...
- P3805 【模版】manacher算法(manacher)
P3805 [模版]manacher算法 题目描述 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 字符串长度为n 输入输出格式 输入格式: 一行小写英文字符a ...
- HihoCode1032 最长回文子串 manacher算法
求最长回文子串的算法比较经典的是manacher算法 转载自这里 首先,说明一下用到的数组和其他参数的含义: (1)p[i] : 以字符串中下标为的字符为中心的回文子串半径长度: 例如:abaa字符串 ...
最新文章
- 内存管理模拟程序c语言,C语言 内存管理详解
- druid抛出的异常------javax.management.InstanceAlreadyExistsException引发的一系列探索
- 数据库之字段数据类型
- C#资源文件与与资源名称字符串之间的互相转化
- 看漫画学python pdf下载_看漫画还能学Python❓❓❓| 0基础小白福音
- 考研【复试技巧】如果复试时太紧张,遇到不会的问题只能凉了吗?这些技巧收下!
- 讲真,做Python一定不要只会一个方向!
- 碎片化学前端,促进技术提升,我推荐这些
- 剑指Offer - 面试题15. 二进制中1的个数(位运算)
- AGC 027D.Modulo Matrix(构造 黑白染色)
- Matrix探究细谈
- 永磁同步电机矢量控制(四)——simulink仿真搭建
- 爬虫技术:scrapy 知识点一
- Redis应用之限制访问频率
- 费雪方程式和交易量公式
- AdGuard免费的电脑手机广告拦截程序
- HPUX——用户解锁
- python--mysql--驱动简介和使用
- 三维重建 几何方法 深度学习_三维重建算法综述|传统+深度学习方式
- 四、指针高级应用总结