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.
思路:动态规划,字符串从第一个字符开始,每在右边增加一个字符i,就判断这个字符与左边的哪些字符(如j的位置,j<=i)可以连成回文,
用flg[k] 记录0-k为止需要截断的次数,则 flg[i]= min( flg[i]=flg[j]+1, flg[i] )(str[j-i]为回文,j可能有多个,所以要用min)
下面第一提交超时:因为每次都判断str[j-i]是否是回文-isPalindrome
class Solution {
public:
bool isPalindrome(string s,int start,int end){
int i=start;
int j=end;
while(i<j){
if(s[i++]!=s[j--])
return false;
}
return true;
}
void setFlgVlaue(string &s,vector<int> &flg,int endIndex)
{
for(int i=endIndex;i>=0;i--){
if(isPalindrome(s,i,endIndex))
flg[endIndex] = (i== 0) ? 0 : min( flg[i-1] + 1 , flg[endIndex] );
}
}
int minCut(string s) {
int ret=0;
if(s.size()==0)
return ret;
vector<int> flg(s.size(),s.size()-1);
flg[0]=0;
for(int i=1;i<s.size();i++){
setFlgVlaue(s,flg,i);
//cout<<flg[i]<<" ";
}
return flg[s.size()-1];
}
};
其实,判断【i,j】是否是回文也可以用动态规划,用isPalindromeFlg[i][j] 表示 i到j是否是回文,则
isPalindromeFlg[i][j] = s[i]==s[j] && isPalindromeFlg[i+1][j-1] , j-i>=2
s[i]==s[j] , j-i<2
class Solution {
public:
void setFlgVlaue(string s,vector<int> &flg,vector<vector<int>> &isPalindromeFlg,int endIndex)
{
for(int i=0;i<=endIndex;i++){ //有等于
if( s[i]==s[endIndex] && ( endIndex-i<2 || isPalindromeFlg[i+1][endIndex-1] ) )
{
isPalindromeFlg[i][endIndex]=true;
flg[endIndex] = (i== 0) ? 0 : min( flg[i-1] + 1 , flg[endIndex] );
}
}
}
int minCut(string s) {
int ret=0;
if(s.size()==0)
return ret;
vector<int> flg(s.size(),s.size()-1);
vector<vector<int>> isPalindromeFlg( s.size(),vector<int>(s.size(),false) );
flg[0]=0;
for(int i=1;i<s.size();i++){
setFlgVlaue(s,flg,isPalindromeFlg,i);
//cout<<flg[i]<<" ";
}
return flg[s.size()-1];
}
};
下面代码从从后往前遍历,往前增加字符(转自
http://www.acmerblog.com/leetcode-solution-palindrome-partitioning-ii-6228.html)
05 | int minCut(string s) { |
06 | const int n = s.size(); |
09 | fill_n(&p[0][0], n * n, false); |
11 | for (int i = 0; i <= n; i++) |
13 | for (int i = n - 1; i >= 0; i--) { |
14 | for (int j = i; j < n; j++) { |
15 | if (s[i] == s[j] && (j - i < 2 || p[i + 1][j - 1])) { |
17 | f[i] = min(f[i], f[j + 1] + 1); |