马拉车算法主要用于解决求在一个序列中求最长回文子串的算法,而且是用复杂度为O(N)的办法来解决这类问题。关于算法的由来以及算法的详细说明,向大家推荐下面这篇文章,自己也是通过下面这篇文章对该算法有了 一个初步的了解。马拉车算法(Manacher's Algorithm) - 简书 (jianshu.com)
下面通过一个例题给出该算法的模板:
题目链接:3188. manacher算法 - AcWing题库
给定一个长度为 n 的由小写字母构成的字符串,求它的最长回文子串的长度是多少。
输入格式
一个由小写字母构成的字符串。
输出格式
输出一个整数,表示最长回文子串的长度。
数据范围
1≤n≤10^7
输入样例:
abcbabcbabcba
输出样例:
13
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=2e7+10;
int p[N];
string newstr="$";
int Manacher()
{
int id=0,mx=0;
int maxv=-1;
int idx=0;
int n=newstr.size()-1;
for(int j=1;j<n-1;j++)
{
p[j]=mx>j?min(p[2*id-j],mx-j):1;
while(newstr[j+p[j]]==newstr[j-p[j]])
p[j]++;
if(mx<p[j]+j)
{
mx=p[j]+j;
id=j;
}
if(maxv<p[j]-1)
{
idx=j;
maxv=p[j]-1;
}
}
return maxv;
}
int main()
{
string str;
cin>>str;
for(int i=0;i<str.size();i++)
{
newstr+="#";
newstr+=str[i];
}
newstr+="#@";
cout<<Manacher()<<endl;
return 0;
}