Palindrome Partitioning
Fill isPal[i][j] once for every substring, using isPal[i][j] = (s[i] == s[j]) and isPal[i+1][j−1]. Then run the same backtracking as the better approach, but each piece check is a table lookup.
Every piece must be a palindrome, so the search cuts s[start..end] only when isPal[start][end] is true. The table answers that in O(1), so no letter is compared again during the search.
Problem
You are given a string s. Cut s into pieces so that every piece is a palindrome. A palindrome reads the same forwards and backwards, such as aa or aba. Find every way to cut s like this. Each way is a list of pieces that, joined in order, give back s.
A string s of lowercase letters.
A list of every valid way to cut s. Each way is a list of pieces.
a, a and b are palindromes, and so are aa and b. The pieces ab and aab are not palindromes, so they cannot be used.
A single letter is a palindrome, so the only way is to keep the whole string as one piece.
aba is a palindrome, so the whole string can be one piece. It can also be cut into a, b and a.
- • 1 ≤ s.length ≤ 16
- • `s` contains only lowercase English letters.
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
Each piece must be a palindrome. Do I need to check the whole string, or only the piece I am cutting off?
- 2.
The answer is every valid way to cut. At the start of the string, what are my choices?
- 3.
After I cut the first piece, what is left? Is that rest the same kind of problem?
- 4.
For
aab, how many places can I cut? How many cut sets is that in total? - 5.
If two different ways of cutting reach the same position, do I need to check the same piece twice?
Brute force approach
Better approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | Try all 2^(n−1) cut sets and keep one only if every piece is a palindrome | O(N · 2^(N−1)) | O(N) |
| Better | Recurse only on palindrome pieces, so a bad piece is never built on | O(N² · 2^N) | O(N) |
| Optimal | Fill a palindrome table in O(N²); the search then checks each piece in O(1) | O(N² + N · 2^N) | O(N²) |
Why does this belong to this pattern?
- “every piece is a palindrome”The rule is checked on each piece, so a bad piece can stop its branch right away.
- “find every way to cut”The answer is a list of all valid cut sets, so every valid route must be kept, not just one count.
- “string”The choices are cut points. After a cut, the rest of the string is the same problem, only shorter.
This is the first string partitioning question. The decision is where each piece ends, and the rule is local: each piece is checked on its own, not the whole string at once. That is different from Valid Palindrome, which checks the whole string once. The next two questions keep the same cut-and-recurse shape, but the rule changes: Restore IP Addresses checks the value and format of each part, and Word Break II checks each piece against a dictionary.
Don't make this mistake
This treats the problem like Valid Palindrome: one check on the whole remainder. On aab, the remainder from start 0 is aab, which is not a palindrome. So every end is skipped, and the answer is [] instead of [[a, a, b], [aa, b]].
The piece a from the first cut stays in path when the search moves on. On aab, the pieces a, a, b are left in place, so the second answer becomes [a, a, b, aa, b]. Its pieces spell aabaab, not aab.
isPal[i+1][j−1] must be filled before isPal[i][j] reads it. With i going up, row i + 1 is still all false. On aaa, isPal[0][2] reads isPal[1][1] too early, gets false, and the answer misses [aaa].
Want to implement this?
Write it yourself on LeetCode, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Backtracking translate into production architectures and low-level memory mechanics.
Foundations: Object-Oriented Principles in C++23
Class invariants, pure virtual interfaces, and RAII smart pointers.
Food Delivery System (Zomato Architecture)
Real-world machine coding application of algorithms and design patterns.
Pointers vs References Deep Dive
Pointer arithmetic and memory layout under the hood.
Virtual Method Table (vtable) & Memory Layout
Polymorphism, vptr overhead, and multiple inheritance in memory.