
熟悉算法的可能知道manacher在线性时间能够找出最长回文串长度,但是要想找出最长回文串是谁,需要做一些改进,这时需要分奇偶讨论,枚举中心点。该题目来源于LeetCode 第五题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
class { public: string longestPalindrome(string s) {
if(s=="") return "";
int idl=0, idr=0, anslen=0; int *r=new int[s.length()+5];
memset(r, 0, sizeof r);
int mx=0, mid=0; for(int i=0; i<s.length(); i++){ r[i]=i<mx ? min(r[2*mid-i], mx-i) : 1;
while(i-r[i]>=0 && i+r[i]<=s.length() && s[i-r[i]]==s[i+r[i]]){ r[i]++; } if(i+r[i]>mx){ mid=i; mx=i+r[i]; }
if(anslen<2*r[i]-1){ anslen=2*r[i]-1; idl=i-r[i]+1; idr=i+r[i]-1; } }
memset(r, 0, sizeof r);
mx=0, mid=0; for(int i=0; i<s.length()-1; i++){ r[i]=i<mx? min(r[2*mid-i], mx-i) : 0;
while(i-r[i]>=0 && i+r[i]+1<s.length() && s[i-r[i]]==s[i+r[i]+1]) r[i]++;
if(i+r[i]>mx){ mid=i; mx=i+r[i]; }
if(anslen<2*r[i]){ anslen=2*r[i]; idl=i-r[i]+1; idr=i+r[i]; } }
string ans=s.substr(idl, anslen);
return ans; } };
|
传统的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
char Ma[MAXN*2]; int Mp[MAXN*2]; void MAnacher(char s[], int len){ int l=0; Ma[l++]='$'; Ma[l++]='#'; for(int i=0; i<len; i++){ Ma[l++]=s[i]; Ma[l++]='#'; } Ma[l]=0; int mx=0, id=0; for(int i=0; i<l; i++){ Mp[i]=mx>i?min(Mp[2*id-i], mx-i):1; while(Ma[i+Mp[i]]==Ma[i-Mp[i]]) Mp[i]++; if(i+Mp[i]>mx){ mx=i+Mp[i]; id=i; } } }
|
近期评论