Brush the process of learning a lot of algorithms, but did not make a note = =, write a little bit to leave an impression ~
1. Manchester algorithm
First, in a very ingenious way, all possible odd/even length palindrome strings are converted to odd lengths: a special symbol is inserted on both sides of each character. For example, Abba becomes #a #b#b#a#, ABA becomes #a #b#a#. In order to further reduce the complexity of the code, you can add another special character at the beginning of the string, so that you do not have to deal with the problem of cross-border, such as $ #a #b#a# (note that the following code is written in C, because the C language specification also requires a string at the end of a ' + ' so just OK, However, other languages may cause cross-border).
The following is an example of string 12212321, which, after the previous step, became s[] = "$ #1 #2#2#1#2#3#2#1#";
Then use an array of p[i] to record the length of the longest palindrome string centered on the character S[i] to the left/right (including s[i], that is, the length of the palindrome string "fold", such as the corresponding relationship between S and P:
S1#2#2#1#2#3#2#1#P1 2 1 2 5 2 1 4 1 2 1 6 1 2 1 2 1(P.S. Can be seen, P[i]-1 is exactly the total length of the palindrome in the original string)
So how do you calculate P[i]? The algorithm adds two helper variables (in fact one is enough, two clearer) ID and MX, where the ID represents the location of the largest palindrome substring center, and MX is id+p[id], which is the boundary of the largest palindrome substring.
Then you can get a very magical conclusion, the key point of this algorithm is here: if mx > I, then p[i] >= MIN (p[2 * id-i], mx-i). This is the string card I have been very long. In fact, if you write it a little more complicated, it will be easier to understand:
When P[j] >= mx-i, the palindrome string centered on s[j] is not necessarily completely contained in a palindrome string centered on S[id], but based on symmetry, the two green boxes are surrounded by the same part, that is, a palindrome string centered on S[i], It will expand to the right at least to the MX position, i.e. P[i] >= mx-i. As to whether the post-MX part is symmetrical, it can only be honestly matched.
For the case of MX <= i, p[i] could not be made more assumptions, only p[i] = 1, and then to match.
Implementation code:
1 Charch1[1000010];2 Charch2[2000010];3 intp[2000010];4 5 voidbuild ()6 {7ch2[0] ='@';8ch2[1] ='#';9 intI, Len =strlen (CH1);Ten for(i =0; i < Len; ++i) One { Ach2[2*i+2] =Ch1[i]; -ch2[2*i+3] ='#'; - } thech2[2*i+2] =' /'; - } - - intSolve () + { -p[0] = p[1] =1; + intID =1, mx =2, MaxLen =0; A for(inti =2; Ch2[i]; ++i) at { -P[i] = mx > I? Min (p[2*id-i], Mx-i):1; - while(Ch2[i+p[i] [= Ch2[i-p[i]]) p[i]++; - if(I+p[i] >mx) - { -MX = i+P[i]; inID =i; - } toMaxLen = Max (MaxLen, p[i]-1); + } - returnMaxLen; the}View Code
Common algorithm Notes