給定乙個字串 s,將 s 分割成一些子串,使每個子串都是回文串。 返回符合要求的最少分割次數。
輸入: "aab"
輸出: 1
解釋: 進行一次分割就可將 s 分割成 ["aa","b"] 這樣兩個回文子串。
class solution(object):
def mincut(self, s):
""":type s: str
:rtype: int
"""n = len(s)
inf = float('inf')
dp = [inf] * (n+1) # dp[i]為字串前i個字元s[0...i-1] 最少可以劃分成 幾個回文串
if n == 0:
return 0
ispalin = self.calcpalin(s) # 判斷回文的二維陣列,isplain[i][j]表示s[i...j]是否是回文串
print(ispalin)
dp[0] = 0
for i in range(n+1):
for j in range(i):
if ispalin[j][i-1] == true: # 表示s[j...i-1]是否是回文串
dp[i] = min(dp[i], dp[j]+1)
return dp[n] - 1 # 返回符合要求的最少分割次數 = 幾個回文串 - 1
# 思想:生成回文串,中心擴充套件,o(n*n)
def calcpalin(self, s):
n = len(s)
f = [[false]*n for _ in range(n)]
# 從中心擴充套件兩邊
# odd 奇數,從 中心字元 向兩邊擴充套件
for c in range(n):
i = j = c
while i >= 0 and j <= n-1 and s[i] == s[j]:
f[i][j] = true
i -= 1
j += 1
# even 偶數,從 中心軸線 向兩邊擴充套件
for c in range(n-1): # 區別
i = c
j = c + 1
while i >= 0 and j <= n-1 and s[i] == s[j]:
f[i][j] = true
i -= 1
j += 1
return f
s = 'aabbac'
s = solution()
print(s.mincut(s)) # 返回切割次數,2
dp[i]:表示字串前i個字元s[0...i-1] 最少可以劃分成 幾個回文串isplain[i][j]:表示s[i...j]是否是回文串
例如,「aabbaac」,切割2次變為[a, abba, c]
isplain陣列為
[true, true, false, false, false, false],
[false, true, false, false, true, false],
[false, false, true, true, false, false],
[false, false, false, true, false, false],
[false, false, false, false, true, false],
[false, false, false, false, false, true]
如草稿圖
思考:如何列印出切割好的各個回文串?
LeetCode 132 分割字串2
給你乙個字串s,請你將s分割成一些子串,使每個子串都是回文。返回符合要求的最少分割次數。示例 1 輸入 s aab 輸出 1解釋 只需一次分割就可將 s 分割成 aa b 這樣兩個回文子串。示例 2 輸入 s a 輸出 0示例 3 輸入 s ab 輸出 1這個需要用到兩次動態規劃,第二次沒有必要搭建...
132 分割回文串 II
給定乙個字串 s,將 s 分割成一些子串,使每個子串都是回文串。返回符合要求的最少分割次數。示例 輸入 aab 輸出 1 解釋 進行一次分割就可將 s 分割成 aa b 這樣兩個回文子串。解法一 public class solution else return dp 0 解法二 如果從分割字串的角...
132 分割回文串 II DP
給你乙個字串 s,請你將 s 分割成一些子串,使每個子串都是回文。返回符合要求的 最少分割次數 示例 1 輸入 s aab 輸出 1 解釋 只需一次分割就可將 s 分割成 aa b 這樣兩個回文子串。示例 2 輸入 s a 輸出 0 示例 3 輸入 s ab 輸出 1 分析 本題利用的最長上公升子串...