【leetcode】132. Palindrome Partitioning II
题目如下:
解题思路:本题是【leetcode】131. Palindrome Partitioning的升级版,要求的是求出最小cuts,如果用【leetcode】131. Palindrome Partitioning的方法把所有解的都求出来取最小值肯定会超时。对于求最大/最小值的题目,大多数情况下都是用动态规划的方法。首先创建dp数组,其长度等于输入字符串s的长度+1,dp[i]表示s[0:i]子串可以划分的最少的回文子串的个数,然后令dp[i]=i (i 是dp[i]最大值,例如输入s= 'abcd',除了单个字符本身之外无任何回文,dp[i] = i)。那么可以得到递推表达式:dp[i] = min(dp[i],dp[j]+1) (0 <j < i && s[j:i]是回文子串)。这样可以得出代码一,提交后发现超时,究其原因,应该多次调用isPalindrom的原因。那么是否可以把isPalindrom的结果存储起来呢?当然可以,继续引入Is_Palidrom[][],令Is_Palidrom[j][i]等于s[j:i]是否回文。那么优化后的判断回文的表达式变成:s[j] == s[i] && Is_Palidrom[j + 1][i - 1] (需满足: j+1 > i-1)。这样得到代码二。
代码一如下:
class Solution(object): def isPalindrom(self,s): return s == s[::-1] def minCut(self, s): """ :type s: str :rtype: int """ dp = [i for i in xrange(len(s)+1)] for i in xrange(len(s)): for j in xrange(i): if self.isPalindrom(s[j:i+1]): dp[i+1] = min(dp[i+1],dp[j]+1) # dp[i+1] = min(dp[i+1],dp[i] + 1) #print dp return dp[-1] - 1
代码二如下:
class Solution(object): def minCut(self, s): """ :type s: str :rtype: int """ t = [False] * (len(s)+1) Is_Palidrom = [] for i in range(len(s)+1): Is_Palidrom.append(t[:]) for i in range(len(s)+1): Is_Palidrom[i][i] = True dp = [i for i in xrange(len(s)+1)] for i in xrange(len(s)): for j in xrange(i): if s[i] == s[j]: if j+1 > i-1: Is_Palidrom[j][i] = True dp[i+1] = min(dp[i+1],dp[j]+1) else: if Is_Palidrom[j + 1][i - 1] == True: Is_Palidrom[j][i] = True dp[i + 1] = min(dp[i + 1], dp[j] + 1) # dp[i+1] = min(dp[i+1],dp[i] + 1) #print dp #print Is_Palidrom return dp[-1] - 1