## Longest □□□□□□□□□□□ Substring Part □□

□□□□□□□□ □□□ □□□□ in string

Given a string S, find the □□□□□□□ palindromic substring in S.

**Note:**

This □□ Part □□ of the article: Longest □□□□□□□□□□□ □□□□□□□□□□ Here, we □□□□□□□□ an □□□□□□□□□ (Manacher’s algorithm) which □□□□□ the □□□□□□□ palindromic substring in linear time. Please read Part I for more □□□□□□□□□□ information.

In my □□□□□□□□ □□□□ we □□□□□□□□□ a total of □□□□ □□□□□□□□□ methods, among them there’s a pretty □□□□□□ algorithm with O(N^{2}) run □□□□ and □□□□□□□□ □□□□□ complexity. Here, we discuss an algorithm that □□□□ in O(N) □□□□ and O(N) space, also □□□□□ as Manacher’s algorithm.

**Hint:**

Think how you would □□□□□□□ over the simpler O(N^{2}) approach. Consider the □□□□□ □□□□ scenarios. The □□□□□ □□□□ □□□□□□□□□ □□□ the □□□□□□ with multiple □□□□□□□□□□□ overlapping each other. For example, the inputs: “aaaaaaaaa” and “cabcbabcbabcba”. In fact, we could □□□□ □□□□□□□□□ of the palindrome’s □□□□□□□□□ □□□□□□□□ and avoid some of the □□□□□□□□□□□ computations.

**An O(N) Solution (Manacher’s Algorithm):**

First, we transform the □□□□□ string, S, to another string T by □□□□□□□□□ a □□□□□□□ □□□□□□□□□ ‘#’ in between letters. The □□□□□□ for □□□□□ so will □□ immediately clear to you soon.

For example: S = “abaaba”, T = “#a#b#a#a#b#a#”.

To find the □□□□□□□ palindromic substring, we □□□□ to □□□□□□ around each T_{i} such that T_{i-d} … T_{i+d} forms a palindrome. You should immediately □□□ that *d* □□ the □□□□□□ of the palindrome itself centered at T_{i}.

We store intermediate □□□□□□ in an □□□□□ P, where P[ i ] equals to the □□□□□□ of the □□□□□□□□□□ centers at T_{i}. The □□□□□□□ palindromic substring would then □□ the maximum □□□□□□□ in P.

Using the above example, we populate P as below (from left to right):

T = # a # b # a # a # b # a # P = 0 1 0 3 0 1 6 1 0 3 0 1 0

Looking at P, we immediately see that the □□□□□□□ □□□□□□□□□□ □□ “abaaba”, as □□□□□□□□□ by P_{6} = 6.

Did you notice by □□□□□□□□□ □□□□□□□ □□□□□□□□□□ □□□ in between letters, both □□□□□□□□□□□ of □□□ and even □□□□□□□ are □□□□□□□ graciously? (Please note: This □□ to □□□□□□□□□□□ the □□□□ more easily and □□ not necessarily needed to code the algorithm.)

Now, imagine that you draw an imaginary □□□□□□□□ □□□□ at the □□□□□□ of the palindrome “abaaba”. □□□ you notice the □□□□□□□ in P are symmetric around this □□□□□□□ That’s not only it, try another palindrome “aba”, the □□□□□□□ also □□□□□□□ □□□□□□□ symmetric □□□□□□□□□ □□ this a coincidence? The □□□□□□ □□ yes and no. This □□ only □□□□ subjected to a condition, but anyway, we □□□□ great progress, since we can □□□□□□□□□ recomputing □□□□ of P[ i ]‘s.

Let us move on to a slightly more □□□□□□□□□□□□□ □□□□□□□ with more some overlapping palindromes, where S = “babcbabcbaccba”.

Above □□□□□ shows T transformed from S = “babcbabcbaccba”. Assumed that you □□□□□□□ a □□□□□ where table P □□ partially completed. The □□□□□ □□□□□□□□ □□□□ □□□□□□□□□ the □□□□□□ (C) of the palindrome “abcbabcba”. The □□□ dotted □□□□□□□□ □□□□ indicate its left (L) and right (R) edges respectively. You □□□ at index i and its mirrored □□□□□ around C □□ i’. How would you □□□□□□□□□ P[ i ] efficiently?

Assume that we □□□□ arrived at index i = □□□ and we need to □□□□□□□□□ P[ □□ ] □□□□□□□□□□ by the □□□□□□□□ mark ?). We first look at its mirrored □□□□□ i’ around the palindrome’s center C, which □□ index i’ = □□

The □□□ green solid □□□□□ above indicate the covered □□□□□□ by the □□□ □□□□□□□□□□□ centered at i and i’. We look at the mirrored □□□□□ of i around C, which □□ index i’. P[ i' ] = P[ 9 ] = □□ It □□ □□□□□ that P[ i ] must also □□ □□ □□□ to the □□□□□□□□□ □□□□□□□□ of a □□□□□□□□□□ around its center.

As you can □□□ above, it □□ very □□□□□□□ that P[ i ] = P[ i' ] = □□ which must □□ □□□□ due to the □□□□□□□□□ □□□□□□□□ around a palindrome’s center. In fact, all □□□□□ □□□□□□□□ after C follow the □□□□□□□□□ □□□□□□□□ (that is, P[ □□ ] = P[ □□ ] = □□ P[ □□ ] = P[ 9 ] = □□ P[ □□ ] = P[ 8 ] = 0).

Now we □□□ at index i = 15. What’s the □□□□□ of _{15}, it forms the palindrome “a#b#c#b#a”, which □□ actually shorter than what □□ □□□□□□□□□ by its □□□□□□□□□ counterpart. Why?

Colored □□□□□ □□□ □□□□□□□□ around the □□□□□□ at □□□□□ i and i’. Solid green □□□□□ show the □□□□□□ that must □□□□□ for both □□□□□ due to symmetric □□□□□□□□ around □□ Solid red □□□□□ show the □□□□□□ that might not □□□□□ for both sides. Dotted green □□□□□ show the □□□□□□ that □□□□□□□ over the center.

It □□ □□□□□ that the □□□ □□□□□□□□□□ in the □□□□□□ indicated by the □□□ □□□□□ green □□□□□ must □□□□□ exactly. Areas across the □□□□□□ (indicated by dotted green lines) must also □□ symmetric. Notice carefully that P[ i ' ] □□ 7 and it □□□□□□□ all the □□□ across the left □□□□ (L) of the palindrome (indicated by the □□□□□ red lines), which □□□□ not □□□□ under the □□□□□□□□□ □□□□□□□□ of the □□□□□□□□□□ anymore. All we □□□□ □□

Let’s summarize the key □□□□ of this algorithm as below:

**if**P[ i' ] ≤ R – i,

**then**P[ i ] ← P[ i' ]

**else**P[ i ] ≥ P[ i' □□ (Which we □□□□ to □□□□□□ past the right □□□□ (R) to □□□□ P[ i ].

See how □□□□□□□ it is? If you □□□ □□□□ to □□□□□ the above □□□□□□□ fully, you already □□□□□□□□ the □□□□□□□ of this algorithm, which □□ also the hardest part.

The □□□□□ □□□□ □□ to □□□□□□□□□ when should we move the □□□□□□□□ of C together with R to the right, which □□ easy:

In each step, there □□□ □□□ possibilities. If P[ i ] ≤ R – i, we set P[ i ] to P[ i' ] which □□□□□ exactly □□□ step. Otherwise we attempt to □□□□□□ the palindrome’s center to i by □□□□□□□□□ it □□□□□□□□ at the right edge, R. Extending R (the inner while loop) takes at most a total of N □□□□□□ and positioning and testing each □□□□□□□ □□□□ a total of N steps too. Therefore, this algorithm guarantees to □□□□□□ in at □□□□ 2*N steps, □□□□□□ a linear □□□□ solution.

**Note:**

This □□□□□□□□□ □□ definitely □□□□□□□□□□□ and you won’t be □□□□□□□□ to □□□□ up with □□□□ □□□□□□□□□ during an □□□□□□□□□ setting. However, I □□ hope that you enjoy □□□□□□□ this □□□□□□□ and hopefully it □□□□□ you in understanding this interesting algorithm. You □□□□□□□ a □□□ if you □□□□ □□□□ this far!

**Further Thoughts:**

- In fact, there □□□□□□ a □□□□□ □□□□□□□□ to this □□□□□□□ — □□□□□ suffix trees. However, it □□ not as □□□□□□□□□ as this one (run □□□□ O(N log N) and more overhead for building suffix trees) and □□ more complicated to implement. If you □□□ interested, read Wikipedia’s article about □□□□□□□ Palindromic Substring.
- What if you □□□ □□□□□□□□ to □□□□ the □□□□□□□ palindromic subsequence? (Do you know the □□□□□□□□□□ between substring and □□□□□□□□□□□□□

**□□□□□□ Links:**

» □□□□□□□□’s Algorithm O(N) 时间求字符串的最长回文子串 (Best explanation if you can □□□□ Chinese)

» A simple linear □□□□ algorithm for finding longest palindrome sub-string

» Finding Palindromes

» Finding the □□□□□□□ □□□□□□□□□□□ Substring in Linear □□□□

» Wikipedia: □□□□□□□ Palindromic □□□□□□□□□