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
posted on 2016-05-26 22:16 Sheryl Wang 阅读(129) 评论(0) 编辑 收藏 举报