当前位置 : 主页 > 手机开发 > ROM >

Palindrome Partitioning II 解答

来源:互联网 收集:自由互联 发布时间:2021-06-10
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

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减少了很多重复计算的时间。

网友评论