A string equal to its own reverse. The recurring difficulty is the odd/even distinction, which every technique handles in its own way.
The toolkit
| Task | Method | Cost |
|---|---|---|
| Is a palindrome? | forward + reverse hashes | |
| Longest palindromic substring | Manacher | |
| Longest palindromic substring | hashing + binary search per centre | |
| Count distinct palindromic substrings | Eertree | |
| Count all palindromic substrings (with multiplicity) | Manacher: | |
| Longest palindromic subsequence | LCS of and | |
| Minimum insertions to make a palindrome | ||
| Minimum cuts into palindromes | DP + a palindrome table | |
| Palindromic factorisation into parts | DP over Eertree series links | |
| Shortest palindrome by prepending | prefix function of |
Manacher’s algorithm
Computes, for every centre, the radius of the longest palindrome around it, in . Handle odd and even centres either with two arrays or by inserting separators:
string t = "^";
for (char c : s) { t += '#'; t += c; }
t += "#$"; // sentinels prevent bounds checks
vector<int> p(t.size(), 0);
int c = 0, r = 0;
for (int i = 1; i + 1 < (int)t.size(); i++) {
if (i < r) p[i] = min(r - i, p[2*c - i]); // mirror
while (t[i + p[i] + 1] == t[i - p[i] - 1]) p[i]++;
if (i + p[i] > r) { c = i; r = i + p[i]; }
}p[i] is then the length of the palindrome centred at in the original string. The separator trick makes every palindrome odd-length, removing the case split entirely — worth the doubled array.
The mirror-and-extend structure is identical to the Z-function’s Z-box; learning one teaches the other.
The hashing alternative
Two hashes (forward and reverse) plus a binary search on the radius gives and about ten lines. For most problems that is enough, and it generalises to variants Manacher cannot express (palindromes with one mismatch allowed, weighted palindromes).
bool isPal(int l, int r) { return fwd.get(l, r) == rev.get(n-1-r, n-1-l); }Palindromic tree (Eertree)
The specialist structure: nodes, one per distinct palindromic substring — and a string of length has at most distinct palindromic substrings, a non-obvious fact that makes the structure linear. See Palindromic Tree.
It is the right tool when the problem is about distinct palindromes or about palindromic factorisations.
Facts worth knowing
- A string of length has at most distinct palindromic substrings.
- Every string can be factored into palindromes (single characters are palindromes); the minimum number is computable in with Eertree series links.
- A string is a palindrome iff its longest border of length pattern holds — more usefully, palindromes of a string form arithmetic progressions by length, which is what makes the factorisation possible.
- Rearrangement into a palindrome is possible iff at most one character has an odd count — a counting check, not a string algorithm.
- The number of palindromic substrings of
aaa...ais with multiplicity but only distinct.
Common problem shapes
- “Longest palindromic substring” → Manacher, or hashing + binary search.
- “Count palindromic substrings” → Manacher (with multiplicity) or Eertree (distinct).
- “Minimum cuts into palindromes” → precompute
isPal[i][j]in , then a linear DP. - “Make it a palindrome with minimum insertions” → − longest palindromic subsequence.
- “Is every prefix a palindrome” / “shortest palindrome by prepending” → prefix function on .
- “Palindromic pairs among words” → hash each word and its reverse, then match.
See also: Manacher · Palindromic Tree · String Hashing