题目:
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.
思路:
Palindrome Partitioning需要收集所有回文切分的解,而这一题只需要求最少的切分次数,如果直接由原来的算法,然后搜索最小切分次数的解,复杂度是 $$O(N^3)$$ ,提交后TLE。
这里需要利用两次DP:
1)首先定义一个二维数组flag[N][N],其中flag[i][j]表示子字符串s[i:j+1]是否是回文,显然若i==j,即长度为1的字符串,则f[i][i]=True,若i+1==j,则需要再查看s[i]和s[i+1]是否相等,如果相等则为True,若j-i>=2,同样先看s[i]和s[j],如果相等,则返回flag[i+1][j-1],否则直接设置为False;
2)再定义一个记录最小切分次数的一维数组count,其中count[i]表示子字符串s[:i+1]的最小切分次数,如果flag[0][i]==True,则为0,否则需要寻找最小的切分方式j,使得count[j]+1最小,且s[j+1:i+1]是回文。
不过可惜,思路虽然没错,但是Python实现依旧TLE,本地跑了一下超时的数据,大概0.807s左右,后来陈大哥用C++实现,AC......
网上看到一个更加简短的Python代码,非常赞,不过同样TLE,一起Po上来吧,三份代码如下,其中C++版本由同实验室陈大哥提供,Python版后面有几个测试数据。。。
bool f[0x1010][0x1010]; class Solution { private: int g[0x1010]; string str; public: int minCut(string s) { str = s; int n = str.length(); for (int i = 0; i < n; ++i) { for (int j = 0; j <= i; ++j) { f[i][j] = true; } } for (int i = 1; i < n; ++i) { for (int j = 0; j < n; ++j) { if (str[j] == str[j + i]) f[j][j + i] = f[j + 1][j + i - 1]; else f[j][j + i] = false; } } g[0] = 0; for (int i = 1; i < n; ++i) { if (f[0][i]) g[i] = 0; else { g[i] = 0x1010; for (int j = 0; j < i; ++j) { if (f[j + 1][i]) g[i] = min(g[i], g[j] + 1); } } } return g[n - 1]; } };
import time class Solution: # @param s, a string # @return a list of lists of string def minCut(self, s): N = len(s) dp = [N-j for j in range(N+1)] p = [[False for i in range(N)] for j in range(N)] for i in xrange(N-1,-1,-1): for j in xrange(i, N): if s[i] == s[j] and (((j - i) < 2) or p[i+1][j-1]): p[i][j] = True dp[i] = min(1+dp[j+1], dp[i]) return dp[0]-1 def minCut2(self, s): N = len(s) if N<=1: return [[s]] count = [-1 for j in range(N)] flag = [[False for j in range(N)] for i in range(N)] for i in xrange(N): flag[i][i] = True if i+1<N and s[i]==s[i+1]: flag[i][i+1] = True for i in xrange(2,N): for j in xrange(N-i): if s[j]==s[j+i] and flag[j+1][j+i-1]: flag[j][j+i] = True count[0] = 0 for i in xrange(1,N): if flag[0][i]: count[i] = 0 else: count[i] = i for j in xrange(i): if flag[j+1][i]: count[i] = min(count[i],count[j]+1) return count[N-1] s = Solution() print s.minCut2('aab') print s.minCut2("fifgbeajcacehiicccfecbfhhgfiiecdcjjffbghdidbhbdbfbfjccgbbdcjheccfbhafehieabbdfeigbiaggchaeghaijfbjhi") print s.minCut2("apjesgpsxoeiokmqmfgvjslcjukbqxpsobyhjpbgdfruqdkeiszrlmtwgfxyfostpqczidfljwfbbrflkgdvtytbgqalguewnhvvmcgxboycffopmtmhtfizxkmeftcucxpobxmelmjtuzigsxnncxpaibgpuijwhankxbplpyejxmrrjgeoevqozwdtgospohznkoyzocjlracchjqnggbfeebmuvbicbvmpuleywrpzwsihivnrwtxcukwplgtobhgxukwrdlszfaiqxwjvrgxnsveedxseeyeykarqnjrtlaliyudpacctzizcftjlunlgnfwcqqxcqikocqffsjyurzwysfjmswvhbrmshjuzsgpwyubtfbnwajuvrfhlccvfwhxfqthkcwhatktymgxostjlztwdxritygbrbibdgkezvzajizxasjnrcjwzdfvdnwwqeyumkamhzoqhnqjfzwzbixclcxqrtniznemxeahfozp") t1 = time.time() print s.minCut2("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") t2 = time.time() print 'finished in %f seconds' % (t2-t1)