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
.
Input: "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.
给定字符串 s
,将 s
分割成一些字符串,使得这些字符串都是回文,求最小的分割次数。
输入: 'aab'
输出: 1
解释: 通过一次分割可以使 'aab' 变为 ['aa', 'b'],这些字符串都是回文。
设 f[i]
为字符串 s[:i+1]
的最小分割次数。计算 f[i]
可以采用动态规划算法。
s[:i+1]
是回文,则需要的最小分割次数为 0。s[:i+1]
不是回文,设 j <= i
且 s[j: i+1]
为回文,则一种可能的分割次数为 f[j-1]+1
,在所有可能的分割次数中求最小即可。在 Palindrome Partitioning 中介绍了如何通过动态规划计算 s
的任意一个子字符串是否是回文的算法,这两者结合即可得到最终结果。
参考代码:
class Solution:
def min_cut(self, s):
n = len(s)
if n < 2:
return 0
dp = [[True] * n for _ in range(n)]
for i in range(n-1, -1, -1):
for j in range(i+1, n):
dp[i][j] = (s[i] == s[j]) and dp[i+1][j-1]
f = [n] * n
for i in range(n):
if dp[0][i]:
f[i] = 0
else:
for j in range(i, 0, -1):
if dp[j][i] and f[j-1] + 1 < f[i]:
f[i] = f[j-1] + 1
return f[-1]
解法 1 通过两次动态规划解决了这个问题,但 dp
数组是一个二维数组,空间复杂度为 O(n^2)
,我们可以对空间复杂度进行优化。
设 f[i]
为字符串 s[:i+1]
的最小分割次数,显然 f[0]=0
。遍历数组 f
,当遍历到 f[i]
时
s[i]
为中心的子字符串是否是回文,可依次判断 s[i-1]==s[i+1]
、s[i-2]==s[i+2]
等等。若子字符串 s[i-j: i+j+1]
为回文,则
i-j==0
,则 f[i+j]=0
i-j!=0
,则可以得到 f[i+j]=min(f[i+j], 1+f[i-j-1])