Palindrome Partitioning II 解答

Posted ireneyanglan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Palindrome Partitioning II 解答相关的知识,希望对你有一定的参考价值。

Question

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.

Example:

Input: "aab" Output: 1 Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.

Solution

第一个思路是和Palindrome Partitioning解答思路相似,先用二维DP得到palindrome结果,然后用DFS.

时间复杂度O(N^2) 空间复杂度O(N^2)

 1 class Solution:
 2     def check(self, s: str) -> None:
 3         n = len(s)
 4         self.dp = [[False for i in range(n)] for j in range(n)]
 5         for i in range(n):
 6             self.dp[i][i] = True
 7         for i in range(n - 1):
 8             if s[i] == s[i + 1]:
 9                 self.dp[i][i + 1] = True
10         for k in range(3, n + 1):
11             for i in range(n - k + 1):
12                 j = i + k - 1
13                 if s[i] == s[j] and self.dp[i + 1][j - 1]:
14                     self.dp[i][j] = True
15     
16     def dfs(self, s: str, start: int, record: List[str], result: List[int]) -> None:
17         n = len(s)
18         if start == n:
19             cut_num = len(record) - 1
20             result[0] = min(cut_num, result[0])
21             return
22         for end in range(start, n):
23             if self.dp[start][end]:
24                 record.append(s[start: end + 1])
25                 self.dfs(s, end + 1, record, result)
26                 record.pop()
27     
28     def minCut(self, s: str) -> int:
29         self.check(s)
30         result = [len(s) - 1]
31         self.dfs(s, 0, [], result)
32         return result[0]
33         

但是这个方法在大数据测试的时候超时了,这时候需要思考怎样可以减少时间。

一个重要的方法是再次使用DP。用一维DP:cut[i]表示从0到i-1的min cut数量。

 1 class Solution:
 2     def check(self, s: str) -> None:
 3         n = len(s)
 4         self.dp = [[False for i in range(n)] for j in range(n)]
 5         # one or two chars
 6         for i in range(n - 1):
 7             self.dp[i][i] = True
 8             self.dp[i][i + 1] = True if s[i] == s[i + 1] else False
 9         self.dp[n - 1][n - 1] = True
10         # more chars
11         for k in range(3, n + 1):
12             for i in range(n - k + 1):
13                 j = i + k - 1
14                 self.dp[i][j] = True if s[i] == s[j] and self.dp[i + 1][j - 1] else False
15     
16     def minCut(self, s: str) -> int:
17         self.check(s)
18         n = len(s)
19         # cut[i] means minimal cut number for s[0:i-1]
20         cut = [len(s) - 1] * (n + 1)
21         # notice here we need to set cut[0] = -1 so that if self.dp[0][n-1] is true, there is no cut needed
22         cut[0] = -1
23         for i in range(1, n + 1):
24             for j in range(i - 1, -1, -1):
25                 if self.dp[j][i - 1]:
26                     cut[i] = min(cut[i], cut[j] + 1)
27         return cut[n]

尽管时间空间复杂度不变,但是在计算最小切割数时我们通过DP减少了很多重复计算的时间。

以上是关于Palindrome Partitioning II 解答的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 131. Palindrome Partitioning

132. Palindrome Partitioning II

palindrome-partitioning I&II——回文切割深度遍历

leetcode 132 Palindrome Partitioning II

Light oj 1044 - Palindrome Partitioning(区间dp)

131. Palindrome Partitioning