solves the longest palindrome substring in a string.
The impression is done before, with the dynamic planning of the interval method, and the method of taking center, Time Complexity O (N) Manacher was unheard of, a good study, for it simply astounding. So now the longest palindrome string of questions to make a summary, in order to turn back to look.
First, enumeration method
Enumerate all substrings (O (N2)) to determine if they are Palindrome (O (N)), Time complexity O (N3), not table.
Second, take the center point method
Enumerate each character Str[i] as the center of the palindrome substring, spread to both sides, compare whether the left endpoint equals the right endpoint, the maximum palindrome length of each character center, enumerate the answers. Time complexity is O (N2), the advantage of this method is good understanding, look comfortable, nature or enumeration, an optimization of the enumeration. But after all it's just O (N2) efficiency, not the best.
Attached code:
#include <stdio.h>#include<string.h>Charstr[50005];inta[50005],n;intFunc1 (intk) { inti,j,sum=1; if(k==0)returnsum; if(k==n-1)returnsum; I=k-1; j=k+1; while(i>=0&& j<N) {if(Str[i]!=str[j])returnsum; Sum+=2; I--;j++; } returnsum;}intFunc2 (intk) { if(k==0)return 1; if(k==n-1)return 1; if(str[k]!=str[k+1])return 0; inti,j,sum=2; I=k-1; j=k+2; while(i>=0&& j<N) {if(Str[i]!=str[j])returnsum; Sum+=2; I--;j++; } returnsum;}intMain () {intlp,i,j,k,sum,ans,tot,m; scanf ("%d",&m); for(lp=1; lp<=m;lp++) {scanf ("%s", str); N=strlen (str); Memset (A,0,sizeof(a)); for(i=0; i<n;i++) {J=func1 (i); K=Func2 (i); A[i]=j>k?j:k; } ans=0; for(i=0; i<n;i++) if(A[i]>ans) ans=A[i]; printf ("%d\n", ans); }}
Func1 () and Func2 () correspond to odd palindrome strings and even palindrome strings, which is easier to write. In short, this method is still relatively refreshing.
Three, the interval dynamic return
Big Love DP.
Say something about moving to return. F[I][J] Indicates whether the substring from I to J is a palindrome, two states f[i][j]=1,f[i][j]=0,
The boundaries are:
F[i][i]=1
if (str[i]==str[i+1]) f[i][i+1]=1; i.e. even palindrome string
The state transition equation is
F[I][J]=F[I+1][J-1]&&STR[I]==STR[J]
It would be nice to ask for the length.
Time complexity O (N2).
#include <stdio.h>#include<string.h>intf[ .][ .],n;Charstr[ .];intMain () {intlp,i,j,k,m,ans=0, Len; scanf ("%d",&m); for(lp=0; lp<m;lp++) {scanf ("%s", str); Memset (F,0,sizeof(f)); N=strlen (str); Ans=0; for(i=0; i<n;i++) {F[i][i]=1; if(i<n-1&&str[i]==str[i+1]) f[i][i+1]=1; } for(len=3; len<=n;len++) for(i=0; i<=n-len;i++) {J=i+len-1; if(f[i+1][j-1]&&str[i]==Str[j]) {ans=Len; F[I][J]=1; }} printf ("%d\n", ans); }}
The point has come.
Iv. Law of Manacher
Time complexity O (N)! It's so wonderful. I understand that there is a little bit of card, code implementation is easy, very good method.
The Manacher method is to enumerate the longest palindrome substrings at the center of each point, using a known, long enough (the center point of the known substring as the ID) to calculate the unknown point I, and to find the point J that is symmetric with I on the ID substring (that is, ID-centric, To find the axis symmetry point of an I point), because this j is known, I and J are also covered by the ID substring, so the palindrome length of I point should be no less than J point. There are two cases, one is that the longest length of a palindrome with the center of J is not more than the coverage of the ID substring, then I can take the length of J directly, and the other is the longest length of J beyond the ID substring coverage, then because of the symmetry of the palindrome string, we can know I The point at least within the coverage of the ID string can be identified as palindrome, when I point should take from I point to the length of the ID string range. The specific contents are as follows.
We use an array p to store the radius of the longest palindrome in the center of each character, ID represents the node to be used, and MX represents the rightmost edge position of the ID string.
As an example,
0 1 2 3 4 5 6 7 8 9 10
A C f c b A B c f c D
Pending point I = 8, id = 5, mx = id+p[id]=10, i+j=2*id, j = 2, p[j]=2
In this example, the ID just covers the i,j two points and we take the p[i]=p[j] directly
If str[0]=b, then the substring of J is [0..4], the ID of the substring [1..9] is not completely covered, we can derive from symmetry, I point at least to 9 this position of the palindrome properties can be determined, 10 this position is not symmetrical still do not know, so we can only take I point to MX, that is p[i]= Mx-i; In a nutshell, that's p[i]=min{p[j],mx-i}; This is the p[i] minimum, and then it expands on that basis to get the right result.
Here is a question to note, that is even type of palindrome what to do, and there is no central point. So, when we initialize, in the string to insert some easy-to-distinguish characters, such as ' # ', so that a ABBA palindrome, become #a #b#b#a#, then this palindrome into a "#" as the center of the palindrome string, the odd palindrome string and even palindrome unified together. Interestingly, when added, P[i]-1 is equal to the length of the original string, which can be easily seen by drawing it yourself.
#include <stdio.h>#include<string.h>intp[2200010],n;Charstr[2200010],s[2200010];voidinit () {inti,j,k; N=strlen (s); str[0]='$'; str[1]='#'; for(i=0; i<n;i++) {Str[i*2+2]=S[i]; Str[i*2+3]='#'; } N=n*2+2; S[n]=0;}voidManacher () {inti,j,mx=0, id=1; for(i=1; i<n;i++) {J=2*id-i; if(mx>i) p[i]=p[j]< (mx-i) p[j]:(mx-i); Elsep[i]=1; for(; Str[i+p[i]]==str[i-p[i]];p [i]++) ; if(i+p[i]>mx) {mx=i+P[i]; ID=i; } }}intMain () {inti,j,k,ans,lp,m; scanf ("%d",&m); for(lp=0; lp<m;lp++) {scanf ("%s", s); Memset (P,0,sizeof(p)); Init (); Manacher (); Ans=0; for(i=1; i<n;i++) if(Ans<p[i]) ans=P[i]; printf ("%d\n", ans-1); }}
Although there is a loop nesting, these two loops do not follow the multiplication principle, the inner loop sweeps only the indeterminate area, so the time complexity is O (N).
The acid is cool!
Longest palindrome substring