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.
保存回文判定结果,动规求解
dp[i]=min(dp[k]+1(s[k+1, i]是回文串, dp[k]+i-k(s[k+1, i]不是回文串)), 0<=k<i.
/*
类似矩阵连乘的动归思路。
dp[i][j]=min(dp[i][k]+dp[k+1][j]+1), i<=k<j.
这个方程的时间是O(n^3),简化dp[i][j]为dp[i],表示从0到i的minCut.
dp[i]=min(dp[k]+1(s[k+1, i]是回文串, dp[k]+i-k(s[k+1, i]不是回文串)), 0<=k<i.
*/
class Solution {
public:
vector<vector<int>> pa;
bool isPalindrome(string &s, int i, int j) {
if( i > j) return false;
if(pa[i][j] != -1) return pa[i][j];
if(i == j) return pa[i][j] = 1;
if(s[i] != s[j]) return pa[i][j] = 0;
else {
if(j-i == 1) return pa[i][j] = 1;
else return pa[i][j] = isPalindrome(s,i+1,j-1);
}
}
int minCut(string s) {
// Note: The Solution object is instantiated only once and is reused by each test case.
int len = s.length();
if(len <= 1) return 0;
vector<int> min,vtmp;
pa.clear();
for(int i = 0; i < len; i++) {
min.push_back(0);
vtmp.push_back(-1);
}
for(int i = 0; i < len; i++) pa.push_back(vtmp);
int tmp,ans;
for(int i = 1; i < len; i++) {
if(isPalindrome(s,0,i)) {
min[i] = 0;
}
else {
ans = len+1;
for(int k = 0; k < i; k++) {
if(isPalindrome(s,k+1,i)) tmp = min[k]+1;
else tmp = min[k]+i-k;
if(tmp < ans) ans = tmp;
}
min[i] = ans;
}
}
return min[len-1];
}
};