Input: "racecarannakayak"Output: ["racecar","anna","kayak"]Explanation: The string "racecarannakayak" can be split into ["racecar","anna","kayak"], where each substring is a palindrome.
To solve this problem, we can use dynamic programming to keep track of the minimum cuts needed to partition the string into palindromic substrings. Here’s the detailed approach:
Dynamic Programming Table: Create a table dp where dp[i] represents the minimum number of cuts needed to partition the substring s[0:i+1] into palindromic substrings.
Palindrome Table: Create a 2D table palindrome where palindrome[i][j] is True if the substring s[i:j+1] is a palindrome.
Initialization: Initialize the palindrome table. If s[i] == s[j] and the substring between them is also a palindrome, then palindrome[i][j] is True.
Filling DP Table: Iterate through the string to fill in the dp table using the palindrome table to determine the minimum cuts required.
Backtracking: Use the dp table to backtrack and find the palindromic substrings.
classSolution:
defminCutPalindromes(self, s: str) -> List[str]:
n = len(s)
dp = [0] * n
palindrome = [[False] * n for _ in range(n)]
for i in range(n):
palindrome[i][i] =Truefor length in range(2, n +1):
for i in range(n - length +1):
j = i + length -1if s[i] == s[j]:
palindrome[i][j] = (length ==2) or palindrome[i +1][j -1]
else:
palindrome[i][j] =Falsefor i in range(n):
if palindrome[0][i]:
dp[i] =0else:
dp[i] = float('inf')
for j in range(i):
if palindrome[j +1][i] and dp[j] +1< dp[i]:
dp[i] = dp[j] +1 result = []
index = n -1while index >=0:
for j in range(index +1):
if palindrome[j][index] and (j ==0or dp[j -1] +1== dp[index]):
result.insert(0, s[j:index +1])
index = j -1breakreturn result
# Example usagesol = Solution()
print(sol.minCutPalindromes("aab")) # Output: ["aa", "b"]print(sol.minCutPalindromes("racecarannakayak")) # Output: ["racecar", "anna", "kayak"]print(sol.minCutPalindromes("abac")) # Output: ["a", "b", "a", "c"]