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,dp+迴文dp
一個二維數組動態規劃記錄是否爲迴文串,一個一維數組dp[i]記錄s[0,i]的最小分割數
當ispalin[j][i]==1時,表示s[j,i]是迴文串,那麼dp[i] = dp[j-1]+1, 初始化dp[i] = i;
class Solution {
public:
int minCut(string s) {
int n = s.size();
vector<vector<bool>> ispalind(n, vector<bool>(n));
vector<int> dp(n);
for(int i = 0; i < n; i++){
dp[i] = i;
for(int j = 0; j<=i; j++)
if(s[i] == s[j] && (i-j<=2 || ispalind[j+1][i-1])){
ispalind[j][i] = 1;
dp[i] = j==0 ? 0: min(dp[j-1]+1,dp[i]);
}
}
for(int i=0;i<n;i++)
cout<<dp[i]<<" ";
return dp[n-1];
}
};
解法2
不使用二維數組來記錄迴文串,直接使用一個n+1維數組進行dp
dp[i]表示前i個字符子串的最小分割數,每次遍歷i時,更新dp[i+len+1]和dp[i+len+2]
dp[i+len+1]更新的是以i爲中心,總長度爲 2len + 1 的迴文串,比如 bob,此時 i=1,len=1
dp[i+len+1]更新的是i爲中心之一,總長度爲 2len + 2 的迴文串,比如 noon,此時 i=1,len=1。
i-len 正好是奇數或者偶數迴文串的起始位置,由於我們定義的 dp[i] 是區間 [0, i-1] 的最小分割數,所以 dp[i-len] 就是區間 [0, i-len-1] 範圍內的最小分割數,那麼加上奇數迴文串長度 2len + 1,此時整個區間爲 [0, i+len],即需要更新 dp[i+len+1]。如果是加上偶數迴文串的長度 2len + 2,那麼整個區間爲 [0, i+len+1],即需要更新 dp[i+len+2]。
class Solution {
public:
int minCut(string s) {
int n = s.size();
vector<int> dp(n+1, INT_MAX);
dp[0] = -1;
for(int i = 0; i < n; i++){
for(int len = 0; i-len>=0 && i+len < n && s[i-len] == s[i+len]; len++)
dp[i+len+1] = min(dp[i+len+1], dp[i-len]+1);
for(int len = 0; i-len>=0 && i+len+1 < n && s[i-len] == s[i+len+1]; len++)
dp[i+len+2] = min(dp[i+len+2], dp[i-len]+1);
}
for(int i=0;i<=n;i++)
cout<<dp[i]<<" ";
return dp[n];
}
};
參考
https://www.cnblogs.com/grandyang/p/4271456.html