具体算法思想参考大佬的文章,比较详细
https://subetter.com/algorithm/manacher-algorithm.html?tdsourcetag=s_pctim_aiomsg
我在代码的基础上做了稍微修改,可以返回最大回文子串的长度,也可以返回最大回文子串。
代码:
#include<bits/stdc++.h>
using namespace std;
string Init(string a)//给字符串a加上#,首字符加上$
{
string s = "$";
s += '#';
for(int i = 0;i < a.length();i++)
{
s += a[i];
s += '#';
}
return s;
}
string Manacher(string a)
{
string s = Init(a);
vector<int> p(s.length());
int max_len = -1;//维护最长的回文子串长度
int id = 0;
int mx = 0;
for(int i = 1; i < s.length();i++)
{
if(i < mx)
p[i] = min(p[2*id-i],mx-i);
else
p[i] = 1;
while(s[i-p[i]] == s[i+p[i]])
p[i]++;
if(mx < i + p[i])
{
id = i;
mx = i + p[i];
}
max_len = max(max_len,p[i]-1);
}
id = 0;
for(int i = 1;i < s.length();i++) //找到最大回文子串的中心位置
if(p[i] > p[id])
id = i;
mx = id + p[id];
string result = "";
for(int i = 2*id-mx+1;i < mx;i++)
{
if(s[i] != '#')
result += s[i];
}
return result;
}
int main()
{
string a;
cin>>a;
if(a.length() <= 1)
cout<<a<<endl;
else
cout<<Manacher(a)<<endl;
return 0;
}