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求出整个字符串的Palindrome情况。然后按长度从1到串长度L来dp求mincut。
关键点在于,假设当前长度为L,那么迭代i(此i为索引值非长度值)从1,2,,,,L-1查看dp(i,L-i)是否Palindrome,如果是那么与mincut比较保存最小值,如果不是,那么直接忽略,可忽略原因是因为在i迭代过程中比当前i大的索引还有机会再计算剩下的dp(i,L-i)是否Palindrome,所以这里可以直接去掉重复计算。
class Solution {
public:
int minCut(string s)
{
const int size = s.length();
vector< vector<bool> > dp(size, vector<bool>(size+1, 0));
for (int len = 1; len <= size; len++)
{
for (int i = 0; i+len <= size; i++)
{
if (len == 1)
dp[i][1] = true;
else if (len == 2 && s[i] == s[i+1])
dp[i][2] = true;
else if (len > 2 && dp[i+1][len-2] == 1 && s[i] == s[i+len-1])
dp[i][len] = true;
}
}
vector<int> dpmin(size , 0);
for (int i = 1; i <= size; i++)
{
int minv = INT_MAX;
if (dp[0][i])
{
dpmin[i-1] = 0;
continue;
}
for (int j = 1; j < i; j++)
{
if (dp[j][i-j])
minv = min(minv, dpmin[j-1] + 1);
}
dpmin[i-1] = minv;
}
return dpmin[size - 1];
}
};
下面是拷的别人的精短代码
class Solution {
public:
int minCut(string s) {
int N = s.size();
bool isP[N];
int dp[N];
dp[0] = 0;
for (int i = 1; i < N; ++i)
{
isP[i] = true;
dp[i] = dp[i-1] + 1;
for (int j = 0; j < i; ++j)
{
isP[j] = (s[i] == s[j]) ? isP[j+1] : false; // isP[j] == true -> [j...i] is a palindrome
// isP[j+1] == true -> [j+1...i-1] is a palindrome
if (isP[j])
dp[i] = (j == 0) ? 0 : min(dp[i], dp[j-1] + 1); // dp[i] -> minCount for [0...i]
}
}
return dp[N-1];
}
};