CMD Guide
HomeDSADynamic Programming

Palindromic Partitioning

Palindromic partitioning works by cutting a string into segments where every segment reads the same forwards and backwards, and it finds the minimum number of cuts by combining two smaller decisions — "is s[i..j] a palindrome?" and "what is the fewest cuts for the prefix ending at i?" — into one bottom-up table, so overlapping sub-answers are computed once instead of exponentially many times.

Recognize the pattern

Brute force → optimal

Brute force: try every subset of cut positions (2^(n-1) ways to place cuts between n-1 gaps), check whether every resulting piece is a palindrome, keep the split with fewest cuts. Cost: exponential in n, plus O(n) per palindrome check per piece — roughly O(2^n · n).

Optimal (DP): first build isPal[i][j] for all substrings in O(n²) time using isPal[i][j] = s[i]==s[j] && (j-i<2 || isPal[i+1][j-1]). Then define cuts[i] = minimum cuts needed for prefix s[0..i]. For each i, scan every j ≤ i where s[j..i] is a palindrome and take cuts[i] = min(cuts[i], j==0 ? 0 : cuts[j-1]+1). This replaces exponential search with O(n²) time.

Complexity, derived

isPal table: n² substrings, each check is O(1) once shorter palindromes are known (fill by increasing length) → O(n²) time, O(n²) space.

cuts array: outer loop over i (n values) × inner loop over j ≤ i (up to n values) = O(n²) operations, each O(1). Total time O(n²), space O(n²) for the palindrome table plus O(n) for cuts — dominated by O(n²).

Compare to brute force's O(2^n · n): for n=16, cuts are placed in 2^(16-1) = 2^15 = 32,768 ways, so brute force does roughly 32,768 × 16 ≈ 524,288 checks versus the DP's 16² = 256 operations — a gap that only grows with n.

Worked example: "cddpd"

Indices 0..4 = c,d,d,p,d. Build isPal (only palindromic spans shown, plus the two lookups needed later): [0,0]="c" ✓, [1,1]="d" ✓, [1,2]="dd" ✓, [2,4]="dpd" ✓ (d==d, middle p trivially palindrome), all single chars ✓. Among the non-palindromic spans, note the two that the cuts[4] derivation below relies on: isPal[2][3]="dp" ✗ (d≠p) and isPal[1][4]="ddpd" ✗ (d==d at the ends, but the inner span isPal[2][3]="dp" is false, so the whole span fails). Other spans such as [0,4]="cddpd" are also ✗.

i (prefix end)best split found scanning jcuts[i]
0 ("c")whole prefix is palindrome, j=00
1 ("cd")no palindromic prefix >1 char; split "c"|"d"1
2 ("cdd")j=1: "dd" is palindrome → cuts[0]+11
3 ("cddp")no long palindrome ending at p; cuts[2]+12
4 ("cddpd")j=2: "dpd" is palindrome → cuts[1]+1 = 1+1 (isPal[1][4] and isPal[2][3] both being false rules out any better split ending at i=4)2

Result: 2 cuts, matching pieces "c", "d", "dpd".

Code

Assumes non-empty input (see pitfalls below for the empty-string edge case).

class Solution {
    public int minCut(String s) {
        int n = s.length();
        boolean[][] isPal = new boolean[n][n];
        for (int i = 0; i < n; i++) isPal[i][i] = true;
        for (int len = 2; len <= n; len++) {
            for (int i = 0; i + len - 1 < n; i++) {
                int j = i + len - 1;
                if (s.charAt(i) == s.charAt(j) && (len == 2 || isPal[i + 1][j - 1])) {
                    isPal[i][j] = true;
                }
            }
        }
        int[] cuts = new int[n];
        for (int i = 0; i < n; i++) {
            if (isPal[0][i]) { cuts[i] = 0; continue; }
            cuts[i] = Integer.MAX_VALUE;
            for (int j = 1; j <= i; j++) {
                if (isPal[j][i] && cuts[j - 1] + 1 < cuts[i]) {
                    cuts[i] = cuts[j - 1] + 1;
                }
            }
        }
        return cuts[n - 1];
    }
}

Pitfalls

When to use / when not — trade-offs

Use this DP when you need the exact minimum cuts and n is small-to-moderate (up to a few thousand, since O(n²) space/time is the ceiling). It beats brute force by pruning shared substring work into a lookup table.

vs. Manacher's algorithm: Manacher finds all palindromic substrings/centers in O(n) but does not by itself solve the partition-minimization problem — it only accelerates building isPal implicitly; you'd still need the O(n²) or better cuts DP on top, so it helps when n is large and the O(n²) isPal table is the bottleneck, not the cuts recurrence.

vs. counting all partitions (backtracking with memoization): if the problem asks to enumerate every valid partition rather than just the minimum cut count, DP alone won't suffice — you need backtracking, optionally pruned by the same isPal table for speed.

Takeaways

Recall: Why does precomputing isPal[i][j] by increasing substring length (not by increasing i) matter for correctness?


Source: adapted and deepened from the study guide's Palindromic Partitioning page (DSA / Dynamic Programming), cross-checked against standard interval-DP treatments of palindrome partitioning (e.g. LeetCode 132 Palindrome Partitioning II).

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

Stuck on Palindromic Partitioning? 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 **Palindromic Partitioning** (DSA) and want to truly understand it. Explain Palindromic Partitioning 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 **Palindromic Partitioning** 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 **Palindromic Partitioning** 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 **Palindromic Partitioning** 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