本题解利用动态规划来计算分割字符串s成回文子串所需的最少分割次数。使用一个列表results,其中results[i]代表字符串s的前i个字符组成的子串分割成回文子串所需的最小次数。初始化results[i] = i - 1,意味着最坏情况下(即每个字符都需要分割),分割次数是i-1。接着,利用两个嵌套循环分别以每个字符为中心扩展寻找回文串。第一个循环寻找以s[i]为中心的奇数长度的回文子串,第二个循环寻找偶数长度的回文子串。若找到回文,则更新results[e+1](e为回文串的终点),使其为results[b] + 1的最小值,这里b是回文串的起点。这样,通过更新results数组,最终results[len(s)]即为将整个字符串s分割成回文子串所需的最少次数。
时间复杂度: O(n^2)
空间复杂度: O(n)
class Solution:
def minCut(self, s: str) -> int:
results = [i-1 for i in range(len(s)+1)] # 初始化dp数组,results[i]是s的前i个字符所需的最小分割次数
for i in range(len(s)):
for j in range(len(s)-i):
b = i - j # 回文起始位置
e = i + j # 回文结束位置
if b < 0 or e >= len(s): break # 边界检查
if s[b] != s[e]: break # 不是回文则终止
results[e+1] = min(results[e+1], results[b]+1) # 更新dp数组
for j in range(len(s)-i):
b = i - j # 回文起始位置
e = i + j + 1 # 回文结束位置
if b < 0 or e >= len(s): break # 边界检查
if s[b] != s[e]: break # 不是回文则终止
results[e+1] = min(results[e+1], results[b]+1) # 更新dp数组
return results[len(s)] # 返回整个字符串所需的最小分割次数