zoukankan      html  css  js  c++  java
  • 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]
  • 相关阅读:
    「JXOI2018」游戏
    「CTSC2018」假面
    CodeForces
    CodeForces
    [Lydsy1710月赛] 小B的数字
    OpenJ_Bailian
    [SDOI2010] 地精部落
    CodeForces
    CodeForces
    [NOI2009] 管道取珠
  • 原文地址:https://www.cnblogs.com/ISGuXing/p/14513453.html
Copyright © 2011-2022 走看看