↓Skip to main content
  1. LeetCode/

LeetCode 1745: Palindrome Partitioning IV

·2 mins· ·
LeetCode Hard Dynamic-Programming Interval-Dp String
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: hard First Attempt: 2026-06-27

  • Submissions: Wrong Answer ×2 → Accepted (brute force) → Accepted ×2 (palindrome table)

Approach
#

  1. Build is_pal[i][j] with interval DP: s[i] == s[j] and the inside is a palindrome (immediate for length <= 2), filled from short to long.
  2. Try both cut points: part 1 [0, i], part 2 [i + 1, j], part 3 [j + 1, n - 1], all non-empty: 0 <= i < j < n - 1.

My Attempts
#

The first three versions sliced the string and checked s == s[::-1], O(n^3). Both WAs were about the cut ranges:

VersionProblem
Attempt 1Skipped j == n - 1 (j is where part 3 starts), missing a one-character last part. For s = "aab", "a" + "a" + "b" works, so the answer is True; it returned False
Attempt 2Removed that restriction, but j started at i, allowing an empty middle part. For s = "abab", "aba" + "" + "b" was accepted; the answer is False and it returned True
Attempt 3, ACStarted j at i + 1, but the slicing brute force took 8 seconds

Building the palindrome table first made it O(n^2).

Solution
#

class Solution:
    def checkPartitioning(self, s: str) -> bool:
        n = len(s)
        is_pal = [[False] * n for _ in range(n)]
        for i in range(n - 1, -1, -1):
            for j in range(i, n):
                is_pal[i][j] = s[i] == s[j] and (j - i < 2 or is_pal[i + 1][j - 1])

        for i in range(n - 2):                     # part 1 is [0, i]
            if not is_pal[0][i]:
                continue
            for j in range(i + 1, n - 1):          # part 2 is [i+1, j], part 3 is [j+1, n-1]
                if is_pal[i + 1][j] and is_pal[j + 1][n - 1]:
                    return True
        return False

Complexity
#

Time O(n^2), space O(n^2).

Mistakes to Avoid
#

  • All three parts must be non-empty; spell out the cut ranges.
  • Slicing and checking each time: O(n^3).

Interview Explanation
#

I build a palindrome table with interval DP: s[i] equal to s[j] with a palindromic inside makes a palindrome. Then I try both cut points, keeping all three parts non-empty, and return True if all three are palindromes. Both steps are O(n^2).

Related

LeetCode 312: Burst Balloons
·2 mins
LeetCode Hard Dynamic-Programming Interval-Dp Array
LeetCode 312 note: choose the last balloon k burst in the range (i, j); at that moment its neighbors are i and j, and the two sides are independent subproblems
LeetCode 3906: Count Good Integers on a Grid Path
·2 mins
LeetCode Hard Dynamic-Programming Digit-Dp
LeetCode 3906 note: the range reaches 9 × 10^15, so no per-number checks; a digit DP carries both lower and upper tight flags, plus the previous digit on the path since path cells must be non-decreasing
LeetCode 1537: Get the Maximum Score
·3 mins
LeetCode Hard Dynamic-Programming Two-Pointers Greedy Array
LeetCode 1537 note: two sorted arrays can switch only at shared values; merge with two pointers, keep a running sum per path, and at a shared value set both to the larger sum plus that value
LeetCode 3816: Lexicographically Smallest String After Deleting Duplicate Characters
·3 mins
LeetCode Hard Stack Monotonic-Stack Greedy String
LeetCode 3816 note: a monotonic stack that deletes a larger top while another copy exists, then trims duplicate letters off the end since a prefix is always smaller
LeetCode 2781: Length of the Longest Valid Substring
·3 mins
LeetCode Hard Sliding-Window Hash-Table String Trie
LeetCode 2781 note: forbidden words are at most 10 long, so each right end checks only the last 10 suffixes; on a match push the left end past it, using the shortest match (the rightmost start)
LeetCode 1458: Max Dot Product of Two Subsequences
·2 mins
LeetCode Hard Dynamic-Programming Longest-Common-Subsequence Array
LeetCode 1458 note: a two-prefix DP; dp[i][j] either pairs nums1[i] with nums2[j] (extending dp[i-1][j-1] or starting fresh) or skips one of them