思路:
利用马拉车算法,求出hwi,代表以i点为中心的回文半径。
求出最长回文子串中心节点的位置,然后,从左右两边取字符即可。
代码:
class Solution {
public:
static const int maxn=1000+10;
int n;
int maxx=0;
int midc=0;
char now[maxn*2];
int hw[maxn*2];
void init(string s)
{
int slen=s.size();
now[0]='!',now[1]='#';
for(int i=0;i<slen;i++)
{
now[2*i+2]=s[i];
now[2*i+3]='#';
}
now[2*n+2]='@';
n=2*n+1;
}
int manacher()
{
int maxright,mid;
maxright=0;
midc=0;
for(int i=1;i<=n;i++)
{
if(i>maxright)hw[i]=1;
else hw[i]=min(hw[mid*2-i],maxright-i);
while(now[i-hw[i]]==now[i+hw[i]])hw[i]++;
if(maxright<i+hw[i])
{
mid=i;
maxright=i+hw[i];
}
if(maxx<hw[i])
{
maxx=hw[i];
midc=i;
}
}
return midc;
}
string longestPalindrome(string s) {
n=s.size();
init(s);
int x=manacher();
//maxx=maxx/2;
int len1=maxx-1;//回文半径
string left="",right="";
int l1=x-1;
while(len1!=0&&l1>=0)
{
if(now[l1]!='#'&&now[l1]!='!'&&now[l1]!='@')
{
left+=now[l1];
}len1--;
l1--;
}
l1=x+1;
len1=maxx-1;
while(len1!=0)
{
if(now[l1]!='#'&&now[l1]!='!'&&now[l1]!='@')
{
right+=now[l1];
}len1--;
l1++;
}
string ss="";
for(int i=0;i<left.size()/2;i++)swap(left[i],left[left.size()-i-1]);
ss+=left;
if(now[x]!='#'&&now[x]!='!'&&now[x]!='@')
{
ss+=now[x];
}
ss+=right;
return ss;
}
};