马拉车算法,mannacher查找最长回文子串
作用:
在线性时间内找到一个字符串的最大回文子串
原理:
奇偶变换:为处理字符串方便,现将给定的任意字符串进行处理,使所有可能的奇数/偶数长度的回文子串都转换成了奇数长度。
具体就是在每个字符的两边都插入一个特殊的符号。比如hhjj变成 #h#h#j#j#, aba变成 #a#b#a#;
为防止数组越界,可以在字符串的开始加入另一个特殊字符,比如“?#a#b#a#?” 。
定义一个辅助数组int p[],p[i]表示以s_new[i]为中心的最长回文的半径,例如:

可以看出,p[i]-1正好是原字符串中最长回文串的长度。
Manacher 算法之所以快,就快在对 p 数组的求法上有个捷径。
if(i < mx)//mx为以id为中心的最远扩展回文串的右边界,i为扫描到的点
{
p[i] = min(p[2 * id - i], mx - i);
}
注解在代码里,例题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std; char str[110010];
char new_s[110010 * 2]; //mannacher数组因为奇偶变换加了符号进去,数组要开原字符串2倍大小
int p[110010 * 2]; void get_news(int len)//构造新字符串
{
new_s[0] = '^';
new_s[1] = '#';
int j = 1;
for(int i = 0; i < len; i ++)
{
new_s[++ j] = str[i];
new_s[++ j] = '#';
}
j ++;
new_s[j] = '\0';
} int mannacher(int len)
{
mem(p, 0);
int mx = 0;
int id = 0;
int maxlen = -1;//答案,最长字符串长度初始化
for(int i = 1; i < len; i ++)
{
if(i < mx)//mx为以id为中心的最远扩展回文串的右边界,i为扫描到的点
{
p[i] = min(p[2 * id - i], mx - i);//需搞清楚上面那张图含义, mx和2*id-i的含义
}
else //i >= mx 不能利用对称性来直接求解p[i]了, 所以先p[i] = 1,然后暴力更新
p[i] = 1;
while(new_s[i - p[i]] == new_s[i + p[i]])//不需边界判断,因为左有'^',右有'\0'
p[i] ++;
if(mx < i + p[i])//每走一步i,都要和mx比较,我们希望mx尽可能的远,这样才能更有机会执行if (i < mx)这句代码,从而提高效率
{
id = i;
mx = i + p[i];
}
maxlen = max(maxlen, p[i] - 1);
}
return maxlen;
} int main()
{
while(scanf("%s", str)!=EOF)
{
int len = strlen(str);
get_news(len);
len = strlen(new_s);
int ans = mannacher(len);
printf("%d\n", ans);
}
return 0;
}
马拉车算法,mannacher查找最长回文子串的更多相关文章
- Manacher (马拉车) 算法:解决最长回文子串的利器
最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...
- Manacher算法讲解——字符串最长回文子串
引 入 引入 引入 Manachar算法主要是处理字符串中关于回文串的问题的,这没什么好说的. M a n a c h e r 算 法 Manacher算法 Manacher算法 朴素 求一个字符串中 ...
- Manacher's Algorithm 马拉车算法(求最长回文串)
作用:求一个字符串中的最长子串,同时还可以求所有子串的长度. 题目链接: https://vjudge.net/contest/254692#problem/B 最长回文串长度的代码: int Man ...
- manacher算法_求最长回文子串长度
很好的总结,转自: http://blog.csdn.net/dyx404514/article/details/42061017 总结为:两大情况,三小情况. 两大情况:I. i <= p 1 ...
- manacher算法学习(求最长回文子串长度)
Manacher总结 我的代码 学习:yyb luogu题目模板 xzy的模板 #include<iostream> #include<cstdlib> #include< ...
- [hdu 3068] Manacher算法O(n)最长回文子串
一个不错的讲解:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/01.05.md # ...
- Manacher算法——求最长回文子串
首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...
- 面试经典算法:马拉松算法,最长回文子串Golang实现
求一个字符串中最长的回文子串. package main import "fmt" /* 马拉松算法,求最长回文子串,时间复杂度:线性 */ func main() { // 回文 ...
- 使用manacher算法解决最长回文子串问题
要解决的问题 求一个字符串最长回文子串是什么.且时间复杂度 O(N) 具体描述可参考: LeetCode_5_最长回文子串 LintCode_200_最长回文子串 暴力解法 以每个字符为中心向左右两边 ...
随机推荐
- ApowerMirror投屏(手机投屏电脑、电脑投屏到手机)
使用步骤 1. 亲测 使用Apowersoft ApowerMirror v1.4.2.zip版本 2.Apowersoft ApowerMirror v1.4.2.zip 解压安装 ...
- 【sklearn】数据预处理 sklearn.preprocessing
数据预处理 标准化 (Standardization) 规范化(Normalization) 二值化 分类特征编码 推定缺失数据 生成多项式特征 定制转换器 1. 标准化Standardization ...
- Windows安装activemq
1.Windows下载解压就可以了,官网:http://activemq.apache.org/ 8161查看端口 61616消息服务端口 2.浏览器访问localhost:8161测试 3.可以在c ...
- Discovery Scanning
1.NetDiscover you performe layer 2 the comand : netdiscover -r 192.168.2.0/24 or use netdiscove ...
- java 根据Url下载对应的文件到指定位置,读txt文件获取url
package test; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; im ...
- 百度地图api文档实现任意两点之间的最短路线规划
两个点之间的路线是使用“Marker”点连接起来的,目前还没找到改变点颜色的方法,测试过使用setStyle没有效果. <html><head> <meta http-e ...
- 金蝶KIS&K3助记码SQL数据库批量刷新
金蝶KIS&K3助记码SQL数据库批量刷新 用的次数不多,就没有写入存储过程或者触发里面了,可以自行实现. 第一步选择对应账套的数据库,执行下面的命令,这个是一个函数. go if exist ...
- js分析 快速定位 js 代码, 还原被混淆压缩的 js 代码
-1.目录 0.参考 1.页面表现 2. 慢镜头观察:低速网络请求 3. 从头到尾调试:Fiddler 拦截 index.html 并添加 debugger; 4. 快速定位 js 代码 5. 还原被 ...
- 一天带你入门到放弃vue.js(二)
接下来我们继续学习一天带你入门到放弃系列vue.js(二),如有问题请留言讨论! v-if index.html <div id="app"> <p v-if=& ...
- BZOJ5254 : [Fjwc2018]红绿灯
显然所有询问都要经过至少$\sum d$,只需要考虑除了$\sum d$之外的等待红灯的时间. 将所有询问的时间模$g+r$,并按时间用set维护. 那么对于每个红灯,在set中可以找出$1$到$2$ ...