最大回文子串--Manacher
最大回文子串----Manacher
思路:
先把原字符串扩充 然后遍历扩充后的数组 用maxx存放最大回文长度 len数组存放他每个下标的的会问长度
时间复杂度O(n)
Code:
#include<iostream>
#include<cmath>
#include<string.h>
using namespace std;
const int N = 1.1e7 + 5;
char s1[N], s2[N * 2];//字符串开N的空间 他的扩展串的空间得开2N
int len[N * 2];//存扩展串长度也得开2N
int maxx, lens;
void gets2()
{
int k = 0;
s2[k++] = '@';//扩展串的第一个不能为字母或者‘#’
lens = strlen(s1);//求原字符串的长度
for (int i = 0; i < lens; i++)
{
s2[k++] = '#';//#与原字符交替赋值
s2[k++] = s1[i];
}
s2[k++] = '#';//最后一个也赋值为#
s2[k] = 0;//结尾
lens = k;// 扩展串长度
}
void manacher()//马拉车算法
{
int id,mx=0;//id为中心位置 mx最大范围的右端
for(int i=0;i<lens;i++)//遍历一遍扩展串
{
if (mx > i) len[i] = min(mx - i, len[id * 2 - i]);
else len[i] = 1;
while (s2[i - len[i]] == s2[i + len[i]]) len[i]++;//如果两端相等就继续判断
if (mx < len[i] + i)//如果最右端的值大于mx 更新mx
{
mx = len[i] + i;//更新mx的值
id = i;//更新中间点的下标
maxx = max(maxx, len[i]);//判断是否更新最大值
}
}
}
int main()
{
cin >> s1;
gets2();
manacher();
cout << maxx - 1 << endl;
return 0;
}
查看8道真题和解析