Palindrome Partitioning IV
HardUpdated: Aug 2, 2025
Practice on:
Problem
Given a string s, return true if it is possible to split the string s
_into threenon-empty palindromic substrings. Otherwise, return _false.
A string is said to be palindrome if it the same string when reversed.
Examples
Example 1
Input: s = "abcbdd"
Output: true
Explanation: "abcbdd" = "a" + "bcb" + "dd", and all three substrings are palindromes.
Example 2
Input: s = "bcbddxy"
Output: false
Explanation: s cannot be split into 3 palindromes.
Constraints
3 <= s.length <= 2000s consists only of lowercase English letters.
Solution
Method 1 – Dynamic Programming for Palindrome Check
Intuition
To split the string into three non-empty palindromic substrings, we can try all possible pairs of split points and check if all three resulting substrings are palindromes. Precomputing all palindromic substrings with DP allows fast checking.
Approach
- Precompute a DP table
isPal[i][j]indicating ifs[i:j+1]is a palindrome. - For all
ifrom 1 to n-2 andjfrom i+1 to n-1, check ifs[0:i],s[i:j], ands[j:n]are all palindromes. - If such a split exists, return true; otherwise, return false.
Code
C++
class Solution {
public:
bool checkPartitioning(string s) {
int n = s.size();
vector<vector<bool>> isPal(n, vector<bool>(n, false));
for (int i = n-1; i >= 0; --i) {
for (int j = i; j < n; ++j) {
if (s[i] == s[j] && (j-i < 2 || isPal[i+1][j-1]))
isPal[i][j] = true;
}
}
for (int i = 1; i < n-1; ++i) {
for (int j = i+1; j < n; ++j) {
if (isPal[0][i-1] && isPal[i][j-1] && isPal[j][n-1])
return true;
}
}
return false;
}
};
Go
func checkPartitioning(s string) bool {
n := len(s)
isPal := make([][]bool, n)
for i := range isPal {
isPal[i] = make([]bool, n)
}
for i := n-1; i >= 0; i-- {
for j := i; j < n; j++ {
if s[i] == s[j] && (j-i < 2 || isPal[i+1][j-1]) {
isPal[i][j] = true
}
}
}
for i := 1; i < n-1; i++ {
for j := i+1; j < n; j++ {
if isPal[0][i-1] && isPal[i][j-1] && isPal[j][n-1] {
return true
}
}
}
return false
}
Java
class Solution {
public boolean checkPartitioning(String s) {
int n = s.length();
boolean[][] isPal = new boolean[n][n];
for (int i = n-1; i >= 0; i--) {
for (int j = i; j < n; j++) {
if (s.charAt(i) == s.charAt(j) && (j-i < 2 || isPal[i+1][j-1]))
isPal[i][j] = true;
}
}
for (int i = 1; i < n-1; i++) {
for (int j = i+1; j < n; j++) {
if (isPal[0][i-1] && isPal[i][j-1] && isPal[j][n-1])
return true;
}
}
return false;
}
}
Kotlin
class Solution {
fun checkPartitioning(s: String): Boolean {
val n = s.length
val isPal = Array(n) { BooleanArray(n) }
for (i in n-1 downTo 0) {
for (j in i until n) {
if (s[i] == s[j] && (j-i < 2 || isPal[i+1][j-1]))
isPal[i][j] = true
}
}
for (i in 1 until n-1) {
for (j in i+1 until n) {
if (isPal[0][i-1] && isPal[i][j-1] && isPal[j][n-1])
return true
}
}
return false
}
}
Python
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):
if s[i] == s[j] and (j-i < 2 or is_pal[i+1][j-1]):
is_pal[i][j] = True
for i in range(1, n-1):
for j in range(i+1, n):
if is_pal[0][i-1] and is_pal[i][j-1] and is_pal[j][n-1]:
return True
return False
Rust
impl Solution {
pub fn check_partitioning(s: String) -> bool {
let n = s.len();
let s = s.as_bytes();
let mut is_pal = vec![vec![false; n]; n];
for i in (0..n).rev() {
for j in i..n {
if s[i] == s[j] && (j-i < 2 || is_pal[i+1][j-1]) {
is_pal[i][j] = true;
}
}
}
for i in 1..n-1 {
for j in i+1..n {
if is_pal[0][i-1] && is_pal[i][j-1] && is_pal[j][n-1] {
return true;
}
}
}
false
}
}
TypeScript
class Solution {
checkPartitioning(s: string): boolean {
const n = s.length;
const isPal: boolean[][] = Array.from({length: n}, () => Array(n).fill(false));
for (let i = n-1; i >= 0; i--) {
for (let j = i; j < n; j++) {
if (s[i] === s[j] && (j-i < 2 || isPal[i+1][j-1]))
isPal[i][j] = true;
}
}
for (let i = 1; i < n-1; i++) {
for (let j = i+1; j < n; j++) {
if (isPal[0][i-1] && isPal[i][j-1] && isPal[j][n-1])
return true;
}
}
return false;
}
}
Complexity
- ⏰ Time complexity:
O(n^2), where n is the length of s. Precomputing all palindromic substrings and checking all split points is quadratic. - 🧺 Space complexity:
O(n^2), for the DP table.