Formatted question description: https://leetcode.ca/all/1745.html

1745. Palindrome Partitioning IV

Level

Hard

Description

Given a string s, return true if it is possible to split the string s into three non-empty palindromic substrings. Otherwise, return false.

A string is said to be palindrome if it the same string when reversed.

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 <= 2000
  • s consists only of lowercase English letters.

Solution

First calculate whether each substring of s is a palindrome. Use a 2D array isPalindrome to store the results so that the results can be obtained efficiently.

Next, loop over i from 0 to s.length() - 3 and loop over j from i + 1 to s.length() - 2. If the substring from index 0 to index i is a palindrome, then check whether the substring from index i + 1 to index j and the substring from index j + 1 to index s.length() - 1 are palindromes. If such i and j exist, return true. Otherwise, return false.

class Solution {
    public boolean checkPartitioning(String s) {
        int length = s.length();
        boolean[][] isPalindrome = new boolean[length][length];
        for (int i = 0; i < length; i++)
            isPalindrome[i][i] = true;
        for (int i = 1; i < length; i++)
            isPalindrome[i - 1][i] = s.charAt(i - 1) == s.charAt(i);
        for (int i = length - 3; i >= 0; i--) {
            for (int j = i + 2; j < length; j++)
                isPalindrome[i][j] = isPalindrome[i + 1][j - 1] && s.charAt(i) == s.charAt(j);
        }
        int maxFirst = length - 3, maxSecond = length - 2;
        for (int i = 0; i <= maxFirst; i++) {
            if (isPalindrome[0][i]) {
                for (int j = i + 1; j <= maxSecond; j++) {
                    if (isPalindrome[i + 1][j] && isPalindrome[j + 1][length - 1])
                        return true;
                }
            }
        }
        return false;

        /* also working, but a little lower efficiency

        for (int i = 0; i <= maxFirst; i++) {
                for (int j = i + 1; j <= maxSecond; j++) {
                    if (isPalindrome[0][i] && isPalindrome[i + 1][j] && isPalindrome[j + 1][length - 1])
                        return true;
                }
        }
        */

    }
}
from typing import List

class Solution:
    def checkPartitioning(self, s: str) -> bool:
        isPalindrome = [ [False] * len(s) for i in range(len(s))]
        for i in range(len(s)):
            isPalindrome[i][i] = True
        for i in range(1, len(s)):
            isPalindrome[i - 1][i] = s[i-1] == s[i]
        for i in range(len(s) - 3, -1, -1):
            for j in range(i + 2, len(s), 1):
                isPalindrome[i][j] = (s[i] == s[j] and isPalindrome[i + 1][j - 1])

        for i in range(len(s) - 2):
            for j in range(len(s) - 1):
                if isPalindrome[0][i] and isPalindrome[i + 1][j] and isPalindrome[j + 1][len(s) - 1]:
                    return True

        return False

if __name__ == "__main__":
    print(Solution().checkPartitioning("abcbdd"))

All Problems

All Solutions