zoukankan      html  css  js  c++  java
  • Palindrome Partitioning II

    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.

    For example, given s = "aab",
    Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.

    这一题求将一个字符串分割成全部为回文子串的最少分割次数,看到最少之类的词,首先想到是DP,确实用DP可以解。

    题目做法很类似于 Word Break这题,状态f[i]定义为前i个字符需要的最少切割为多少个回文字符串(注意不是最少切割次数,主要是为了方便处理全部字符都是回文的情况)。f[i] = min(f[j] && s[j][i-1]为回文。初始化f[i] = i(最多分为i 个)。结果为f[len(s)]-1(得到实际的切割次数)。

    注意在求回文的时候,我开始想到的办法是每次再从头和尾向中间扫,判断是不是回文。但是注意每次判断回文的中间有很长片段是重复的,之前判断过的。显然DP又可以出马了,一种是先将字符串是否为回文的二维矩阵提前求出,之后在求最少切割个数,另一种是两个操作并行进行,后者要快于前者。

    前者代码为:

    class Solution(object):
        def minCut(self, s):
            """
            :type s: str
            :rtype: int
            """
            if not s:
                return 0
            res = range(len(s)+1)
            pal = self.isPal(s)
            res[0] = 0
            for i in xrange(1,len(s)+1):
                for j in xrange(i):
                    if pal[j][i-1]:
                        if j == 0:
                            res[i] = 1
                        res[i] = min(res[i],res[j]+1)
            return res[len(s)]-1
            
        def isPal(self,s):
            pal = [[False for i in xrange(len(s))] for i in xrange(len(s))]
            for i in xrange(len(s)):
                for j in xrange(i+1):
                    if s[i] ==  s[j] and (j+1 > i-1 or pal[j+1][i-1]):
                        pal[j][i] = True 
            return pal

    后者代码如下:

    class Solution(object):
        def minCut(self, s):
            """
            :type s: str
            :rtype: int
            """
            if not s:
                return 0
            res = range(len(s)+1)
            pal = [[False for i in xrange(len(s))] for i in xrange(len(s))]
            res[0] = 0
            for i in xrange(1,len(s)+1):
                for j in xrange(i):
                    if s[i-1] == s[j]:
                        if j+1 > i-2 or pal[j+1][i-2]: #j+1 > i - 2表示长度为2。这种情况下也无法再继续减长比较。 
                          pal[j][i-1]  = True
                          res[i] = min(res[i],res[j]+1)
            return res[len(s)]-1

    注意以上使用O(n^2)空间复杂度的解法并非最优,还存在O(n)空间复杂度的解法,代码见leetcode discussion 

     
  • 相关阅读:
    CSS标题省略号带后缀名称
    vue post下载
    PiNetwork – 国外手机挖矿,目前国外热度很高
    iview table expand 单击当前行控制
    iview 开关变化时控制状态的变更
    CSS伪元素before,after制作左右横线中间文字效果
    idea 修改代码自动编译
    如何获取微信公众号的关注链接?
    震惊,微信小程序可以设置网络字体!真香
    小程序字体大小怎么设置,小程序修改字体样式方法
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5532894.html
Copyright © 2011-2022 走看看