132. 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.
Example:
Input: “aab”
Output: 1
Explanation: The palindrome partitioning [“aa”,“b”] could be produced using 1 cut.
方法1: dynamic programming
grandyang:https://www.cnblogs.com/grandyang/p/4271456.html
思路:
首先确定dp[i]的一个一维dp,含义为(0,i)之内需要最少多少个cut,那么我们首先将dp initialize 成n + 1。那么转移方程是什么呢?对于dp[i]来说,我们从头开始找最后一个cut的位置。从j = 0 开始,首先判断[j, i]之间是否是palindrome。这里需要另一个dp来辅助判断palindrome, 我们不需要重复的遍历i,j之间的字符,而是用回文串问题的一般做法,建立一个isPal[i][j]matrix,记录[i, j]之间字符串是否回文。那么每次对于[i, j],我们只需要知道s[i]和s[j]是否相等,[i + 1, j - 1]是否回文。这里的base case是i == j(此时自动满足s[i] == s[j])或者i - j = 1(此时需要如果s[i] == s[j]),对这些case,要直接set isPal[i][j] = true。如果[i, j]区间内不构成回文串,可以直接跳过。下一步确定了[i, j],当j > 0 的时候我们向dp[j - 1],查询[0, j - 1]的区间内需要cut多少次,+1后和dp[i]去较小值。当j == 0时,说明整个[i, j]回文,需要0 cut,应该特殊处理。
Complexity
Time complexity: O(n^2)
Space complexity: O(n^2)
class Solution {
public:
int minCut(string s) {
int n = s.size();
vector<int> dp(n, n + 1);
vector<vector<int>> isPal(n, vector<int>(n, false));
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j ++) {
if (s[i] == s[j] && (i - j <= 2 || isPal[j + 1][i - 1])) {
isPal[j][i] = 1;
dp[i] = min(dp[i], (j == 0) ? 0 : (dp[j - 1] + 1) );
}
}
}
return dp.back();
}
};