InterviewPrepKit

Home / Coding / Backtracking

Palindrome Partitioning

medium Original β†—
Solving tips
  • This is partition-style backtracking: try each palindromic prefix s[start:end], recurse on the suffix, then undo; record when start reaches the end.
  • Prune within the loop by only recursing on prefixes that are palindromes, so invalid cuts are never extended.
  • Optionally precompute an interval DP table is_pal[i][j] (fill by shorter substrings first) to make each palindrome check O(1).
  • Time is O(n * 2^n) (up to 2^(n-1) partitions, each O(n) to build), O(n) recursion space; snapshot with path[:] and keep slice-bound conventions consistent.

Problem

Given a string s, partition it into contiguous substrings such that every substring is a palindrome. Return all possible such partitions.

A partition is an ordered list of non-empty pieces whose concatenation is exactly s. Each piece must read the same forwards and backwards (a single character is trivially a palindrome). Two partitions are different if they cut the string at different positions.

The order of the partitions in your answer does not matter, but within each partition the pieces must appear left to right as they occur in s.

Examples

  • Input: s = "aab" β†’ Output: [["a", "a", "b"], ["aa", "b"]] "a" | "a" | "b" splits every character (all trivially palindromes). "aa" | "b" merges the first two since "aa" is a palindrome. "aab" as one piece is not a palindrome, so it is excluded.
  • Input: s = "a" β†’ Output: [["a"]] A single character has exactly one partition.
  • Input: s = "aba" β†’ Output: [["a", "b", "a"], ["aba"]] Split into singletons, or keep the whole string since "aba" is itself a palindrome. "ab" | "a" is invalid because "ab" is not a palindrome.

Constraints

  • 1 <= s.length <= 16.
  • s consists of lowercase English letters only.

The short length (<= 16) is the signal that an exponential enumeration of cut points is expected β€” there can be up to 2^(n-1) partitions.

Think about it first

Hint 1 Think about the first cut. The initial piece is some prefix `s[0:i]`. It is only allowed if that prefix is a palindrome. Once you commit to it, you face the same problem on the remaining suffix.
Hint 2 This is a classic build-a-path-and-backtrack shape: choose a palindromic prefix, recurse on the rest, then undo the choice and try a longer prefix. When you consume the whole string, record the current list of pieces.
Hint 3 The palindrome check for `s[start:end]` is done many times. You can precompute a 2-D table `is_pal[i][j]` = "is `s[i..j]` a palindrome" with dynamic programming, so each check during backtracking is O(1).
Your workspace Not runnable by design β€” this is your interview scratchpad. Saved on this device.