You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Assume that we have arrived at index i = 13, and we need to calculate P[ 13 ] (indicated by the question mark ?). We first look at its mirrored index i’ around the palindrome’s center C, which is index i’ = 9.
The two green solid lines above indicate the covered region by the two palindromes centered at i and i’. We look at the mirrored index of i around C, which is index i’. P[ i' ] = P[ 9 ] = 1. It is clear that P[ i ] must also be 1, due to the symmetric property of a palindrome around its center.
47
-
As you can see above, it is very obvious that P[ i ] = P[ i' ] = 1, which must be true due to the symmetric property around a palindrome’s center. In fact, all three elements after C follow the symmetric property (that is, P[ 12 ] = P[ 10 ] = 0, P[ 13 ] = P[ 9 ] = 1, P[ 14 ] = P[ 8 ] = 0).
Now we are at index i = 15, and its mirrored index around C is i’ = 7. Is P[ 15 ] = P[ 7 ] = 7?
51
-
Now we are at index i = 15. What’s the value of P[ i ]? If we follow the symmetric property, the value of P[ i ] should be the same as P[ i' ] = 7. But this is wrong. If we expand around the center at T15, it forms the palindrome “a#b#c#b#a”, which is actually shorter than what is indicated by its symmetric counterpart. Why?
Colored lines are overlaid around the center at index i and i’. Solid green lines show the region that must match for both sides due to symmetric property around C. Solid red lines show the region that might not match for both sides. Dotted green lines show the region that crosses over the center.
55
-
It is clear that the two substrings in the region indicated by the two solid green lines must match exactly. Areas across the center (indicated by dotted green lines) must also be symmetric. Notice carefully that P[ i ' ] is 7 and it expands all the way across the left edge (L) of the palindrome (indicated by the solid red lines), which does not fall under the symmetric property of the palindrome anymore. All we know is P[ i ] ≥ 5, and to find the real value of P[ i ] we have to do character matching by expanding past the right edge (R). In this case, since P[ 21 ] ≠ P[ 1 ], we conclude that P[ i ] = 5.
else P[ i ] ≥ P[ i' ]. (Which we have to expand past the right edge (R) to find P[ i ].
62
-
See how elegant it is? If you are able to grasp the above summary fully, you already obtained the essence of this algorithm, which is also the hardest part.
64
+
else P[ i ] ≥ P[ i' ] 这里我们需要扩展右边R来找到P[i]
65
+
```
66
+
67
+
该算法是如此的简洁。如果可以抓到上述要害,就完全领悟了该算法的精髓,也是最难理解的部分。
63
68
64
-
The final part is to determine when should we move the position of C together with R to the right, which is easy:
69
+
最后我们就要决定何时同时向右移动C和R的坐标:
70
+
71
+
```
72
+
如果回文的中心i越过了R,我们就将C更新成i,(该回文的新中心),然后把R扩展到新回文的右边。
73
+
```
65
74
66
-
If the palindrome centered at i does expand past R, we update C to i, (the center of this new palindrome), and extend R to the new palindrome’s right edge.
67
-
In each step, there are two possibilities. If P[ i ] ≤ R – i, we set P[ i ] to P[ i' ] which takes exactly one step. Otherwise we attempt to change the palindrome’s center to i by expanding it starting at the right edge, R. Extending R (the inner while loop) takes at most a total of N steps, and positioning and testing each centers take a total of N steps too. Therefore, this algorithm guarantees to finish in at most 2*N steps, giving a linear time solution.
75
+
论时间复杂度,有两种可能性。如果P[i] ≤ R – i,只需一步,我们设P[i]为P[i']。否则,我们从右边R扩展,改变回文的中心变为i。扩展R(线性while循环)需要花费N步,而且确定坐标也需要花费N步。所以,该算法确保在2*N步内,提供了线性时间复杂度的解法。
68
76
69
77
```
70
-
// Transform S into T.
71
-
// For example, S = "abba", T = "^#a#b#b#a#$".
72
-
// ^ and $ signs are sentinels appended to each end to avoid bounds checking
This algorithm is definitely non-trivial and you won’t be expected to come up with such algorithm during an interview setting. However, I do hope that you enjoy reading this article and hopefully it helps you in understanding this interesting algorithm. You deserve a pat if you have gone this far! :)
In fact, there exists a sixth solution to this problem — Using suffix trees. However, it is not as efficient as this one (run time O(N log N) and more overhead for building suffix trees) and is more complicated to implement. If you are interested, read Wikipedia’s article about Longest Palindromic Substring.
127
-
What if you are required to find the longest palindromic subsequence? (Do you know the difference between substring and subsequence?)
128
-
Useful Links:
129
-
» Manacher’s Algorithm O(N) 时间求字符串的最长回文子串 (Best explanation if you can read Chinese)
130
-
» A simple linear time algorithm for finding longest palindrome sub-string
131
-
» Finding Palindromes
132
-
» Finding the Longest Palindromic Substring in Linear Time
0 commit comments