问题描述:
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
给定一个字符串s,找出最长的子串。
样例:
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Input: "cbbd"
Output: "bb"
马拉车分为3种情况:
1.i<mx时,代表可以在以id为中心的回文串中找到对应点 2*id-i.如果以i为中心的回文串最右未到达mx,则p[i]=p[2*id-i]
2..i<mx时,如果以i为中心的回文串最右边超过了mx,则不可以完全使用对称性,但是在mx范围内的仍是回文串,即p[i]=mx-i;
3.i>mx时,无参考情况,所以p[i]=1.
代码如下:
#include<iostream>
#include<string.h>
#include<cmath>
#include<algorithm>
using namespace std;
int p[2005];
string manacher(string s){
int len=s.length();
int maxlen=0,maxi=0;
string ss="";
ss+='#';
for(int i=0;i<len;i++){
ss+=s[i];
ss+="#";
}
int len1=ss.length();
int mr=0,mid=0;//回文串涉及到的最右边以及其中间值
p[0]=1;
for(int i=1;i<len1;i++){
if(i<mr){
p[i]=min(p[2*mid-i],mr-i);
}
else if(i>=mr){
p[i]=1;
}
while(i-p[i]>=0 && ss[i-p[i]]==ss[i+p[i]]){//要记住越界判断,若在最开始插入一个$,可以排除越界问题,因为不会有相等
p[i]++;
}
if(mr<i+p[i]){
mr=i+p[i];
mid=i;
}
if(p[i]>=maxlen){//更新最大值
maxlen=p[i];
maxi=i;
}
}
return s.substr(maxi/2-(maxlen-1)/2,maxlen-1);
}
int main(){
memset(p,0,sizeof(p));
string s;
getline(cin,s);
cout<<manacher(s)<<endl;
return 0;
}