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 

     
  • 相关阅读:
    个人案例分析
    软工结对作业
    交点问题
    C语言复习
    【软件工程】提问回顾与个人总结
    【技术博客】Arxiv的新Paper获取和机翻
    【技术博客】动态面包屑导航
    对对碰 -- 软工结对编程博客
    交点计数 -- 软工个人项目作业
    面向对象的程序设计-模块四课程总结
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5532894.html
Copyright © 2011-2022 走看看