Palindrome partitioning II (min cuts)
Hard TimeO(n²) SpaceO(n²)
Cut a string so that every piece reads the same backwards, using as few cuts as possible. The cuts fall between characters and the pieces are contiguous. Cutting between every character always works, since a single character is a palindrome, so the question is how few will do — and a string that is already a palindrome needs none.
Examples
Example 1
- Input
- s = "aab"
- Output
- One cut gives
1aaandb, both palindromes; uncut,"aab"is not one.
Example 2
- Input
- s = "aba"
- Output
0"aba"already reads the same backwards, so no cut is needed at all.
The Code
function minCut(s) {
const n = s.length;
const isPal = [];
for (let i = 0; i < n; i++) {
isPal.push(new Array(n).fill(false));
}
for (let end = 0; end < n; end++) {
for (let start = end; start >= 0; start--) {
if (s[start] === s[end] && (end - start < 2 || isPal[start + 1][end - 1])) {
isPal[start][end] = true;
}
}
}
const cuts = new Array(n).fill(0);
for (let end = 0; end < n; end++) {
if (isPal[0][end]) {
cuts[end] = 0;
continue;
}
let best = end;
for (let start = 1; start <= end; start++) {
if (isPal[start][end] && cuts[start - 1] + 1 < best) {
best = cuts[start - 1] + 1;
}
}
cuts[end] = best;
}
return cuts[n - 1];
}
minCut("aab");Done
The first 19 calls, of 25. This one does not fit on a page.
More like this
All dynamic programming examples (20) →- Climbing stairs Count the ways to the top — Fibonacci in disguise.
- Coin change Try every coin and keep the cheapest way to make the amount.
- Max subarray One pass, two running totals — Kadane’s algorithm.
- LCS Match a character or drop one from either string.
- Edit distance Insert, delete, or replace — take the cheapest at each mismatch.
- 0/1 Knapsack For each item, take it or leave it — keep the more valuable branch.