题目:
Given a string s, partition s such that every substring of the partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
For example, given s = "aab"
,
Return 1
since the palindrome partitioning ["aa","b"]
could be produced using 1 cut.
解题思路
- 序列型动态规划 - Sequence DP
- cache[i]表示前i个字符组成的字符串需要最少cut几次保证子串都是回文串(或能被分割成多少个回文串 - 1)
- 初始化cache[i] = i -1
- cache[0] = -1 (因为前0个字符串被分割成0个回文串,0 - 1 = -1)
- 状态转移方程:cache[i] = min(cache[j] + 1)
满足条件的j应该是- j < i
- j+1 ~ i 这一段是回文串
- 对于判断某一段是否是回文串,使用区间型动态规划可以将时间复杂度从O(n)优化到O(1)
代码:
class Solution(object):
def minCut(self, s):
"""
:type s: str
:rtype: int
"""
if not s:
return 0
IsPalindrome = self.getIsPalindrome(s)
cache = [0 for _ in range(len(s) + 1)]
for i in range(len(s) + 1):
cache[i] = i - 1
for i in range(1, len(s) + 1):
for j in range(i):
if IsPalindrome[j][i - 1]:
cache[i] = min(cache[i], cache[j] + 1)
return cache[len(s)]
def getIsPalindrome(self, str):
IsPalindrome = [[False for i in range(len(str))] for i in range(len(str))]
"""
initialize (0, 0), (1, 1)......
and (0, 1), (1, 2)......
"""
for i in range(len(str)):
IsPalindrome[i][i] = True
for i in range(len(str) - 1):
if str[i] == str[i + 1]:
IsPalindrome[i][i + 1] = True
for length in range(2, len(str)):
for start in range(0, len(str) - length):
IsPalindrome[start][start + length] = \
IsPalindrome[start + 1][start + length - 1] and str[start] == str[start + length]
return IsPalindrome