LeetCode132:分割回文串(DP、回文)

 解题思路:有两个问点:1、如何快速当前字符串哪些的字串是回文;2、如何组合这些字串达到分割次数最少

针对问点1,可以开辟一个二维布尔数组 a[][],a[i][j]表示以索引i为起点,j为结束位置的字符串是否是回文串。那么有递推公式a[i][j] = a[i+1][j-1] &&(s[i]==s[j]) (i<j); a[i][j] = True (i>=j)。不难发现 a 数组可以在N*N的复杂度内完成。

针对问点2,本人一开始想的是一个(N*N*N)的算法,设置二维dp数组 dp[i][j]表示索引i为起点,j为结束位置的字符串的最小分割次数。枚举(i,j)区间,从而得到dp[0][N-1]的值,但是仔细观察,似乎可以去掉一个维度,设置一维dp数组 dp[i]表示以0为起点,i为结束位置的字符串的最小分割次数,枚举(0,i)区间,从而得到dp[N-1]的值,时间复杂度(N*N),于是得到状态转移方程 如果a[k][i]是回文串,那么dp[i] = max(dp[i],dp[k]+0+1),因为最终的分割次数,一定是和分割点的个数相同,即只有a[k][i]是回文串的时候才可能有状态转移。

 

 1 class Solution:
 2     def minCut(self, s):
 3         length = len(s)
 4         is_hui = [[0]*length for i in range(length)]
 5         for i in range(length-1,-1,-1):
 6             for j in range(0,length,1):
 7                 if i >=j:
 8                     is_hui[i][j] = 1
 9                 else:
10                     is_hui[i][j] = is_hui[i+1][j-1] and (s[i]==s[j])
11         inf = int(1e9)
12         dp = [inf for i in range(length)]
13         for i in range(length):
14             if is_hui[0][i]:
15                 dp[i] = 0
16         #print(dp)
17         for i in range(length):
18             for k in range(0,i):
19                 if is_hui[k+1][i]:
20                     dp[i] = min(dp[i],dp[k]+1)
21         #print(dp)
22         return dp[-1]

 

posted @ 2021-03-10 18:20  ISGuXing  阅读(135)  评论(0编辑  收藏  举报