DP LeetCode132 分割回文串 II

2021-10-07 14:20:48 字數 2021 閱讀 7033

給定乙個字串 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 分析 本題利用的最長上公升子串...