Shortest Palindrome

HardStrings · KMP · Rolling Hash🧩 String MatchingLeetCode #214 ↗Updated

Problem

You may only prepend characters to the string s. Return the shortest palindrome you can produce this way.
Inputs = "aacecaaa"Output"aaacecaaa"
Inputs = "abcd"Output"dcbabcd"
Inputs = ""Output""

0 ≤ s.length ≤ 5 · 104  ·  lowercase English letters

Try it yourself

Java
class Solution {
    public String shortestPalindrome(String s) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
The answer is reverse(tail) + s, where the kept head is the longest palindromic prefix of s. That prefix is the longest prefix of s that is also a suffix of reverse(s) — exactly what the KMP prefix function of s + '#' + reverse(s) reports at its last position.
PatternString Matching

Instinct Find a pattern in a text, or a prefix that is also a suffix, faster than O(n·m) - reach for the KMP prefix function or a rolling hash.

Memory hack KMP remembers borders, Rabin-Karp compares fingerprints - neither one re-reads text it has already seen.

Open the String Matching guide →

Approaches

Brute ForceShrink the Prefix Until It Is a Palindrome

Time O(n2)Space O(n)

Try prefix lengths end = n, n-1, ... and test each with two pointers. The first palindromic prefix is the longest one; everything after it, reversed, is what must be prepended.

Java
public String shortestPalindrome(String s) {
    int end = s.length();
    while (end > 0 && !isPalindrome(s, 0, end - 1)) end--;
    return new StringBuilder(s.substring(end)).reverse() + s;
}

private boolean isPalindrome(String s, int lo, int hi) {
    while (lo < hi) {
        if (s.charAt(lo++) != s.charAt(hi--)) return false;
    }
    return true;
}

Obvious and correct, but strings like aaa…ab cost quadratic time.

At a glance

LevelApproachTimeSpace
Brute ForceShrink the Prefix Until It Is a PalindromeO(n2)O(n)
BetterRolling Hash of Prefix vs Its ReverseO(n) expectedO(n)
OptimalKMP Prefix Function on s + '#' + reverse(s)O(n)O(n)
Common pitfalls
  • Appending instead of prepending — the problem only allows adding to the front.
  • Running KMP on s + reverse(s) without a separator — borders can exceed n.
  • Forgetting the empty string — it is already a palindrome.
Interview tips
  • Reduce the problem aloud: find the longest palindromic prefix; the rest follows.
  • Present the O(n2) scan first, then explain why KMP's border = palindromic prefix.
  • Mention Rabin–Karp or Manacher as alternatives and the collision caveat for hashing.
Pattern
KMP prefix function → longest prefix that is also a suffix of some transformed string (here s#rev(s)).
My notes saved in this browser