Palindrome Partitioning II

HardString DP · Palindrome Table / Centre Expansion🧩 String DPLeetCode #132 ↗Updated

Problem

Split the string s into consecutive pieces so that every piece is a palindrome. Return the smallest number of cuts that makes this possible (a string that is already a palindrome needs 0 cuts).
Inputs = "aab"Output1 ("aa" | "b")
Inputs = "a"Output0
Inputs = "ab"Output1

1 ≤ s.length ≤ 2000  ·  lowercase English letters

Try it yourself

Java
class Solution {
    public int minCut(String s) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Let cut[k] be the best answer for the first k characters. Any palindrome s[l..r] gives cut[r+1] ≤ cut[l] + 1. Generating every palindrome by expanding around centres relaxes all these edges with no n×n table.
PatternString DP

Instinct Two strings compared char by char (match, edit, interleave) means dp[i][j] over prefixes; one string's palindromes or splits means dp[l][r] or dp[i].

Memory hack Match? Go diagonal. Mismatch? Ask the neighbours. Up drops a char from s, left drops one from t, diagonal uses both.

Open the String DP guide →

Approaches

Brute ForceRecursion over Palindromic Prefixes

Time O(n·2n)Space O(n)

parts(start) = fewest palindromic pieces covering s[start..]: try every end where s[start..end] is a palindrome and recurse on the rest. Cuts = pieces − 1.

Java
public int minCut(String s) {
    return parts(s, 0) - 1;
}

private int parts(String s, int start) {
    if (start == s.length()) return 0;
    int best = Integer.MAX_VALUE;
    for (int end = start; end < s.length(); end++) {
        if (isPalindrome(s, start, end)) best = Math.min(best, 1 + parts(s, end + 1));
    }
    return best;
}

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

Explores every partition; fine for tiny strings, hopeless at n = 2000.

At a glance

LevelApproachTimeSpace
Brute ForceRecursion over Palindromic PrefixesO(n·2n)O(n)
BetterPalindrome Table + 1-D Cut DPO(n2)O(n2)
OptimalCentre Expansion Relaxing a Cut ArrayO(n2)O(n)
Common pitfalls
  • Returning the number of pieces instead of cuts — off by one.
  • Greedily taking the longest palindromic prefix — "aaba"-style inputs break it.
  • Building the full table and running Palindrome Partitioning I's backtracking — exponential.
Interview tips
  • Separate the two sub-problems: is s[i..j] a palindrome? and min cuts for a prefix.
  • Explain why cut[l] is final when read: every palindrome ending before l was already seen.
  • Mention the table's memory (n2 booleans) as the motivation for centre expansion.
Pattern
Prefix DP + palindrome oracle → minimise pieces when each piece must satisfy a substring property.
My notes saved in this browser