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 

 
原文地址:https://www.cnblogs.com/sherylwang/p/5532894.html