CMD Guide
HomeDSADynamic Programming

Longest Palindromic Substring

A palindrome is symmetric around a center, so instead of checking all O(n²) substrings from scratch, you can grow outward from each possible center (there are 2n-1 of them, counting between-character centers for even-length palindromes) and stop the moment the two ends stop matching — the DP variant instead builds up the answer for longer substrings from the verified answers for shorter ones, since a substring s[i..j] is a palindrome iff s[i]==s[j] AND s[i+1..j-1] is a palindrome (or has length ≤ 1).

Recognize the pattern

Brute force → optimal

ApproachIdeaTimeSpace
Brute forceCheck every substring for palindrome-nessO(n³)O(1)
DP (table)Build dp[i][j] from shorter intervalsO(n²)O(n²)
Expand around centerGrow outward from each of 2n-1 centersO(n²)O(1)
Manacher's algorithmReuse mirror symmetry to skip re-checksO(n)O(n)

Brute force wastes work: checking s[i..j] takes O(j-i) time on its own, and there are O(n²) pairs (i,j), giving O(n³). The DP/expand-around-center approaches cut the per-substring check to O(1) by reusing previously computed results, dropping to O(n²).

Complexity, derived

DP table version: dp[i][j] = true iff s[i]==s[j] and (j-i<2 or dp[i+1][j-1]). We fill the table by increasing substring length L = 1..n. For each L there are (n-L+1) starting positions i, and each cell costs O(1) to compute from an already-filled cell. Total work = Σ_{L=1}^{n} (n-L+1) · O(1) = O(n²) operations. Space is the full n×n boolean table = O(n²).

Expand-around-center version: there are exactly 2n-1 centers (n single-character centers + n-1 between-character centers for even-length palindromes). Expanding from one center costs O(k) where k is the palindrome's half-length, and in the worst case (all same character, e.g. "aaaa") a center can expand O(n) steps. Summed over all centers, worst case is O(n) centers × O(n) expansion = O(n²) time, O(1) extra space since no table is stored.

Worked example: s = "cddpd"

Indices: s[0]='c', s[1]='d', s[2]='d', s[3]='p', s[4]='d'. Using expand-around-center, try each odd center (i) and each even center (between i,i+1):

CenterExpansionPalindrome foundLength
0 ('c')can't expand (boundary)"c"1
1 ('d')s[0]='c' vs s[2]='d' → stop"d"1
2 ('d')s[1]='d' vs s[3]='p' → stop"d"1
3 ('p')s[2]='d' vs s[4]='d' → match, expand once; boundary next"dpd"3
4 ('d')can't expand"d"1
between 0,1s[0]='c' vs s[1]='d' → no match0
between 1,2s[1]='d' vs s[2]='d' → match, expand once: s[0]='c' vs s[3]='p' → stop"dd"2
between 2,3s[2]='d' vs s[3]='p' → no match0
between 3,4s[3]='p' vs s[4]='d' → no match0

Best found: "dpd", length 3 — the even-center match at (1,2) produces "dd" (length 2), which is a real intermediate result but is beaten by the odd-center-3 result, matching the expected output.

Reference implementation (expand around center)

public class LongestPalindromicSubstring {
    public String longestPalindrome(String s) {
        if (s == null || s.length() < 1) return "";
        int start = 0, maxLen = 1;
        for (int i = 0; i < s.length(); i++) {
            int len1 = expand(s, i, i);       // odd length, center at i
            int len2 = expand(s, i, i + 1);   // even length, center between i,i+1
            int len = Math.max(len1, len2);
            if (len > maxLen) {
                maxLen = len;
                start = i - (len - 1) / 2;
            }
        }
        return s.substring(start, start + maxLen);
    }

    private int expand(String s, int left, int right) {
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
        }
        return right - left - 1; // length of palindrome found
    }
}

Pitfalls

When to use / when not

Use expand-around-center when you just need the longest palindromic substring and want O(n²) time with O(1) extra space — simplest to code correctly under interview pressure. Use the DP table when you also need to answer "is s[i..j] a palindrome?" for arbitrary ranges afterward (e.g. counting all palindromic substrings), since the table gives O(1) lookups post-construction at the cost of O(n²) space. Reach for Manacher's algorithm only when n is large (10⁴–10⁶) and true O(n) is required — it's correct but fiddly to implement from memory, so it's a poor default choice unless the constraints demand it.

Takeaways

Recall: Why does expand-around-center need to try 2n-1 centers instead of just n?


Sources: CLRS-style substring DP treatment; standard expand-around-center technique as used in LeetCode 5 (Longest Palindromic Substring); Manacher's algorithm for the O(n) extension.

🤖 Don't fully get this? Learn it with Claude

Stuck on Longest Palindromic Substring? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Longest Palindromic Substring** (DSA) and want to truly understand it. Explain Longest Palindromic Substring from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Longest Palindromic Substring** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Longest Palindromic Substring** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Longest Palindromic Substring** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes