Visual walkthrough — Palindrome algorithms — Manacher's algorithm
We are answering one question the whole way down:
"At each spot in a string, how far does the palindrome around it reach — without re-checking ground we already checked?"
Step 1 — What is a palindrome, drawn as a mirror
WHAT. A palindrome is a string that reads the same forwards and backwards:
racecar,abba,b. Pick a center and the string is a mirror image of itself around that center.
WHY we care about the center. Every palindrome has a middle. If we know, for each possible middle, how far the mirroring reaches, we know every palindrome in the string. So the whole problem becomes: for each center, find the radius.
PICTURE. Below,
abcbais drawn with its center on thec. The green arrows show that position equals , and equals . The radius is how many matched pairs we get before the mirror breaks — here it is .

There are two annoying flavours: odd palindromes (aba, center is a letter) and even ones (abba, center is the gap between two letters). We fix this next.
Step 2 — The # trick: make every palindrome odd
WHAT. Insert a spacer
#between every character and at both ends.abbabecomes#a#b#b#a#. We call this new string .
WHY. An even palindrome has its center between two characters — there is no single index to stand on. After padding, that "between" gap is now occupied by a real
#. So every palindrome in is centered on an actual index of , and every one has odd length. One uniform case instead of two.
PICTURE. The top row is
abba. The bottom row is#a#b#b#a#. The old even center (the gap between the twobs) is now the highlighted#at index — a real position we can stand on.

Related tools that solve the "find longest palindrome" task more slowly live at Longest Palindromic Substring and Expand Around Center — we are about to beat both.
Step 3 — The slow way, and exactly why it hurts
WHAT. Naive method: stand at each center , and expand outward one step at a time, comparing with until they differ. That is Expand Around Center.
WHY it's correct but slow. It is obviously correct. But look at
aaaa. Every center can expand almost across the whole string, so we do roughly comparisons at centers → about work. That is .
PICTURE. The red brackets show the expansion at three different centers of
aaaa#-style input. Notice the massive overlap — the same characters get compared again and again. That wasted re-comparison is the enemy we will now eliminate.

Step 4 — The rightmost palindrome: the memory we carry
WHAT. As we sweep from left to right, we remember the single palindrome found so far that reaches furthest right. We store it as two numbers:
- ==== — its center index in .
- ==== — the index just past its right edge (its right boundary).
WHY these two. A palindrome centered at with right edge reaches steps each way, so it covers the interval . Knowing tells us exactly which region of is "already understood by symmetry." Everything about the trick happens inside this region.
PICTURE. The blue palindrome sits on the number line. is its center, its right wall, and its left wall (found by reflecting across ). The shaded band is our "known-mirror zone."

Step 5 — The mirror copy, and the wall that limits it
WHAT. Suppose our new center lies inside the blue palindrome, i.e. . Its mirror buddy is , which we already visited (it is to the left). We tentatively set .
WHY. Inside the blue palindrome, position and position are mirror images. Whatever palindrome exists at is reflected to — as long as that reflected palindrome stays inside the blue walls. But if is so big that the mirrored palindrome would poke past , we have no guarantee out there: symmetry only promises what is inside the blue region. So we must cap the copy at the distance to the wall, which is .
PICTURE. Two scenarios side by side.
- Left (Case A): the buddy's palindrome (yellow) fits strictly inside the blue walls. Its mirror at (also yellow) is an exact, complete copy. , and no expansion is possible.
- Right (Case B): the buddy's palindrome runs into (or past) the left wall . Its mirror at is only guaranteed up to the right wall . Beyond we are blind, so we cap at and must try to expand.

Step 6 — Expand past the wall (only when needed)
WHAT. After the mirror copy, we try to push further: while the characters just outside our current radius still match — — increase by one.
WHY only sometimes. In Case A the copy is already maximal; the very first comparison fails, so the loop does zero work. In Case B we genuinely might extend past into unknown territory — that is the only place real comparisons happen. Then, if our new right edge passes the old , we have found a new rightmost palindrome, so we update , .
PICTURE. A Case-B center. The yellow part (up to the wall) came free from the mirror. The green part is the new expansion past , discovered by real comparisons. The red wall then jumps rightward to the new edge.

Step 7 — Why the total work is (amortized)
WHAT. Add up all the expansion comparisons across the entire run.
WHY it's linear. The mirror step is per index — no loop. The only loop is the expand loop, and every successful comparison there moves one step to the right. starts at and never decreases, and it can reach at most . So across the whole algorithm, the expand loop runs at most successful steps total — not per index, total. Plus one failed comparison per center. Grand total .
PICTURE. 's value plotted against the sweep index . It is a monotone staircase climbing from to . The area of climbing = total expansion work = bounded by the height . This is the same accounting idea as in Amortized Analysis.

Step 8 — The degenerate cases, so nothing surprises you
WHAT. The corners that break naive code.
PICTURE. Four tiny strings —
a,aa,abc,aaaa— each with its final array printed underneath, so you can see the pattern in every regime.

The one-picture summary
PICTURE. The whole algorithm on one canvas: the blue rightmost palindrome , a new center inside it, its mirror buddy , the free copy (yellow) capped at the wall, the paid expansion (green) past , and the wall jumping to its new spot. This single diagram is Manacher's algorithm.

Related structures that also enumerate palindromes: Palindromic Tree (Eertree). The mirror/reuse idea echoes the Z-Algorithm and the KMP failure function — all three amortize by carrying a "reach so far" boundary.
Recall Feynman: retell the whole walkthrough in plain words
We had a string and wanted, for every possible middle, how far the mirror reflection reaches. Even-length mirrors were annoying, so we sprinkled # spacers to make every mirror odd — one clean shape. Then we noticed: if a big mirror already covers our new spot, the left side of that big mirror was already measured, and by symmetry it equals the right side. So we just peek at the mirror buddy and copy its answer — for free — but only as far as the big mirror's wall reaches; past the wall we know nothing. Where the buddy's answer runs into the wall, we roll up our sleeves and measure by hand, one step at a time, pushing the wall forward. Because the wall only ever moves forward and can only travel the length of the string, all the hand-measuring in the whole run adds up to just one pass. Mirror when you can, push the wall when you must — linear time.
Recall Self-check
On s="abba" with t="#a#b#b#a#", what is and why? ::: : center # at index 4, mirror gives 0 but we sit exactly on the wall, so we must expand — and we uncover the whole abba, radius/length .
Why is the mirror step capped at ? ::: Symmetry only guarantees what lies inside the rightmost palindrome; past the wall we have no information, so we cannot copy beyond it.
Why is total expansion ? ::: Every successful expand comparison pushes one step right; never retreats and maxes at , so total expansions .