Welcome to Subscribe On Youtube
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; } } */ } } ############ class Solution { public boolean checkPartitioning(String s) { int n = s.length(); boolean[][] g = new boolean[n][n]; for (var e : g) { Arrays.fill(e, true); } for (int i = n - 1; i >= 0; --i) { for (int j = i + 1; j < n; ++j) { g[i][j] = s.charAt(i) == s.charAt(j) && (i + 1 == j || g[i + 1][j - 1]); } } for (int i = 0; i < n - 2; ++i) { for (int j = i + 1; j < n - 1; ++j) { if (g[0][i] && g[i + 1][j] && g[j + 1][n - 1]) { return true; } } } return false; } }
-
// OJ: https://leetcode.com/problems/palindrome-partitioning-iv/ // Time: O(N^2) // Space: O(N^2) class Solution { public: bool checkPartitioning(string s) { unsigned N = s.size(), h[2001][2001] = {}, rh[2001][2001] = {}, d = 16777619; for (int i = 0; i < N; ++i) { int hash = 0; for (int j = i; j < N; ++j) { hash = hash * d + s[j] - 'a'; h[i][j] = hash; } } reverse(begin(s), end(s)); for (int i = 0; i < N; ++i) { int hash = 0; for (int j = i; j < N; ++j) { hash = hash * d + s[j] - 'a'; rh[N - j - 1][N - i - 1] = hash; } } for (int i = 0; i < N; ++i) { // first part [0,i] if (h[0][i] != rh[0][i]) continue; for (int j = i + 1; j < N - 1; ++j) { // second part [i+1,j], last part [j+1,N-1] if (h[i + 1][j] == rh[i + 1][j] && h[j + 1][N - 1] == rh[j + 1][N - 1]) return true; } } return false; } };
-
# 1745. Palindrome Partitioning IV # https://leetcode.com/problems/palindrome-partitioning-iv/ class Solution(): def checkPartitioning(self, s): n = len(s) dp = [[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]: # j-i<=2: # case-1: j-i==0, single char itself # case-12: j-i==1, e.g. 'aa' # case-1: j-i==j, e.g. 'aba' dp[i][j] = (j - i <= 2) or dp[i+1][j-1] return any(dp[0][i-1] and dp[i][j-1] and dp[j][n-1] for i in range(1, n-1) for j in range(i+1, n)) # below is 2nd solution 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"))
-
func checkPartitioning(s string) bool { n := len(s) g := make([][]bool, n) for i := range g { g[i] = make([]bool, n) for j := range g[i] { g[i][j] = true } } for i := n - 1; i >= 0; i-- { for j := i + 1; j < n; j++ { g[i][j] = s[i] == s[j] && (i+1 == j || g[i+1][j-1]) } } for i := 0; i < n-2; i++ { for j := i + 1; j < n-1; j++ { if g[0][i] && g[i+1][j] && g[j+1][n-1] { return true } } } return false }