题目:
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.
思路:
1)利用一个动态划归的数组来保持palindrome的状态。DP[i][j]表示从i到j的字符串是否是palindrome,为了减少计算量,我们可以首先计算i,j相差为0的字符串,显然DP[k][k]=true。然后检查相差为2,3,…,n的时候可以利用已有的计算成果。运算复杂度从O(n3)减少为O(n2)。 2)再次运用动态规划来找到最佳划分组合。DP2[i]表示长度为i的字符串的最小划分次数。显然,k1<k2时,DP2[k1]<DP2[K2],所以已知DP2[1],DP2[2],…DP2[n]时,求n +1只需要找到第一个满足k到n+1的字符串是palindrome的DP2[k]。
代码:
class Solution {
public:
bool** dp;
int min;
int cur;
int minCut(string s) {
if(s.size()>0)
{
dp = new bool*[s.size()];
for(int i=0;i<s.size();i++)
{
dp[i] = new bool[s.size()];
}
for(int i=0;i<s.size();i++)
{
for(int j=0;j<s.size()-i;j++)
{
dp[j][j+i]=isPalindrome(s,j,j+i);
}
}
int* dp2 = new int[s.size()+1];
dp2[0]=-1;
dp2[1]=0;
if(dp[0][1])
dp2[2] = 0;
else
dp2[2] = 1;
for(int i=2;i<s.size();i++)
{
int min=i;
for(int j=0;j<=i;j++)
{
if(dp[j][i])
{
int cur = dp2[j] + 1;
if(cur<min)
min=cur;
}
}
dp2[i+1] = min;
}
return dp2[s.size()];
}
else
{
return 0;
}
}
bool isPalindrome(string s, int i, int j)
{
if(i==j)
{
return true;
}
else if(i+1==j)
{
return s[i]==s[j];
}
else
{
if(dp[i+1][j-1])
{
return s[i]==s[j];
}
else
{
return false;
}
}
}
};