Backtracking · Medium

155. Count Palindromic Partitions of a String

Topics: Backtracking, Dynamic Programming

Solve it on DeVert Campus - free code runner

Problem

Given a string s, count the number of distinct ways to partition it into one or more contiguous substrings such that every substring is a palindrome.

Input and output

Input: A single line containing the string s. Output: Print a single integer - the number of ways to partition s into palindromic substrings.

Example

Input:
aab
Output:
2

Constraints

1 <= |s| <= 200

Key observation

This is the 'count' version of 'Print All Palindromic Partitions' - the same recursive structure, but returning a count instead of building and collecting every actual partition, which is exactly what makes memoization straightforward here (you can't easily memoize a list of ALL partitions the same way you can memoize a simple count).

Intuition

Count how many distinct ways a string can be split into pieces where every piece is itself a palindrome. Brute force: Try every possible way to insert cut points across the whole string and check if EVERY resulting piece is a palindrome - this checks partitions combinatorially without pruning early, and re-checks the same substring's palindrome status repeatedly across different partition attempts. Optimised: Precomputing a DP table of 'is substring [i,j] a palindrome' ONCE (in O(n²)) turns every palindrome check during the counting recursion into an O(1) lookup instead of an O(n) re-verification - combined with memoizing the COUNT of ways to partition each suffix, this avoids the exponential blowup of naive recursive counting.

Approach 1

Use backtracking: at each position, try every prefix of the remaining suffix, check (from scratch) whether it is a palindrome, and if so recurse on what's left, counting a valid partition whenever the recursion consumes the whole string. This explores every possible partition and is correct, but re-checking palindromes character by character inside an already-exponential search makes it very slow. Time: O(2^n * n) Space: O(n)

Better - Top-Down Memoized Recursion

Precompute nothing extra, but memoize the recursive function on the starting index, so that count(i) (the number of palindromic partitions of the suffix starting at i) is computed once and reused instead of being recomputed for every path that reaches index i. Palindrome checks are still done naively per substring, so the work is bounded by the number of distinct (start, end) substring checks across all recursive calls, a large improvement over the un-memoized exponential blowup. Time: O(n^3) Space: O(n^2)

Optimal - Palindrome Table + Bottom-Up DP

First build a 2D boolean table isPal[i][j] marking whether s[i..j] is a palindrome, filled in O(1) per cell using the fact that s[i..j] is a palindrome exactly when s[i] equals s[j] and s[i+1..j-1] is a palindrome. Then compute dp[i] = number of ways to partition s[0..i-1], where dp[i] = sum of dp[j] over all j < i such that s[j..i-1] is a palindrome (an O(1) lookup now). Combining the two removes the repeated substring recomputation entirely, giving quadratic time overall. Time: O(n^2) Space: O(n^2)

Step by step

1. Try every possible FIRST cut, but only recurse into it if the piece before the cut is itself a palindrome. 2. Recursively count the ways to partition the remaining suffix the same way, summing contributions from every valid first cut. 3. Precomputing which substrings are palindromes with a DP table upfront avoids re-checking the same range's palindrome-ness repeatedly.

Complexity

Time: O(n²) with both the palindrome-precomputation table and memoized partition-counting. Space: O(n²) for the palindrome table, plus O(n) for the memoized counts array.

Edge cases

Test |s| = 1 (always 1 way), a string made of one repeated character (many palindromic partitions), and |s| = 200 for performance.

Interview tip

Be ready to explain the TWO layers of optimization here (precomputed palindrome table, AND memoized partition counts) - using only one without the other still leaves real inefficiency on the table.

All DSA problems