Last Updated: April 2, 2026
We need to make the string s into a palindrome by only adding characters to the front. The key question is: what is the minimum number of characters we need to prepend?
Think about it this way. If s already starts with a long palindrome, we only need to reverse the leftover suffix and stick it in front. For example, in "aacecaaa", the prefix "aacecaa" is a palindrome. The remaining suffix is just "a", and since that's already part of the palindrome structure, we only need to prepend one "a".
So the real problem reduces to: find the longest palindromic prefix of s. Once we know that, the answer is the reverse of the remaining suffix, prepended to s.
The brute force approach checks palindromic prefixes directly. But for a string up to 50,000 characters, we need something smarter. This is where the KMP failure function (or rolling hash) comes in, turning a seemingly difficult string problem into an elegant pattern matching exercise.
0 <= s.length <= 5 * 10^4 → With n up to 50,000, an O(n^2) approach would mean up to 2.5 billion operations, which is too slow. We need O(n) or O(n log n).s consists of lowercase English letters only → No special characters to worry about. Simple character comparisons.0 <= s.length → Empty string is valid input. Handle this edge case.The most direct approach: try every possible prefix of s, starting from the longest, and check if it's a palindrome. The first palindromic prefix we find (going longest to shortest) gives us the answer.
Once we know the longest palindromic prefix of length k, the characters from index k to the end form the suffix that isn't part of the palindrome. We reverse that suffix and prepend it to s.
Why start from the longest? Because the longer the palindromic prefix, the fewer characters we need to add, giving us a shorter result.
n down to 1:s[0..k-1] is a palindrome by comparing characters from both ends.s[k..n-1].s.This approach works but is too slow for large inputs. What if we could find the longest palindromic prefix in a single pass, without checking each prefix individually?
Here's the key insight that makes this problem elegant. Finding the longest palindromic prefix of s is equivalent to finding the longest prefix of s that matches a suffix of reverse(s).
Why? If s[0..k-1] is a palindrome, then reading those characters forward gives the same result as reading them backward. The reversed string rev ends with the reverse of s's prefix, and if that prefix is a palindrome, the reverse of the prefix equals the prefix itself. So the prefix of s matches the suffix of rev.
This is exactly what the KMP failure function solves. Build the string s + "#" + reverse(s), compute the failure table, and the last value tells us the length of the longest palindromic prefix.
The # separator is crucial. Without it, the failure function might find a "match" that spans across s and reverse(s), giving a false result longer than s itself.
The KMP failure function finds the longest proper prefix of a string that is also a suffix. When we build s + "#" + reverse(s), a prefix of s that is a palindrome will match with a suffix of reverse(s). Since reverse(s) ends with the reverse of s's beginning, a palindromic prefix reads the same forwards and backwards, creating exactly the kind of prefix-suffix match the failure function detects.
The # separator prevents the match from crossing the boundary. Without it, the failure function could report a match longer than s itself, which would be meaningless.
s is empty, return "".rev = reverse of s.combined = s + "#" + rev.combined:fail[i] = length of the longest proper prefix of combined[0..i] that is also a suffix.fail[0] = 0.i from 1 to end:j = fail[i-1].j > 0 and combined[i] != combined[j], set j = fail[j-1].combined[i] == combined[j], increment j.fail[i] = j.fail[len(combined) - 1] gives the length of the longest palindromic prefix.s after that prefix, reverse it, and prepend to s.The KMP approach is guaranteed correct with no collisions, but it allocates extra strings and a failure table. Can we find the longest palindromic prefix using hash-based comparison with minimal extra space?
Instead of explicitly building and comparing strings, we can use hashing. The idea is to maintain two rolling hashes as we scan through s: one for the prefix read forward, and one for the same prefix read backward. When both hashes match at some position i, the prefix s[0..i] is (very likely) a palindrome.
We process the string from left to right, updating both hashes incrementally. Whenever the forward hash equals the backward hash, we record that position as a candidate for the longest palindromic prefix. After scanning the entire string, the last recorded match gives us the answer.
The forward hash computes s[0]*base^(i) + s[1]*base^(i-1) + ... + s[i]*base^0 (treating the string as a polynomial). The backward hash computes s[i]*base^(i) + s[i-1]*base^(i-1) + ... + s[0]*base^0. These two polynomials evaluate to the same value modulo a prime if and only if s[0..i] reads the same forwards and backwards, i.e., it's a palindrome.
By updating both hashes incrementally, we check every prefix in O(1) per character, achieving O(n) total time.
forwardHash = 0, backwardHash = 0, power = 1, and bestLen = 0.i from 0 to n-1:forwardHash by appending s[i]: forwardHash = forwardHash * base + s[i].backwardHash by prepending s[i]: backwardHash = backwardHash + s[i] * power.power = power * base.forwardHash == backwardHash, record bestLen = i + 1.s[bestLen..], reverse it, and prepend to s.