题目
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回符合要求的最少分割次数。
示例:
输入: “aab”
输出: 1
解释: 进行一次分割就可将 s 分割成 [“aa”,“b”] 这样两个回文子串。
解析
一、这题主要想不到的就是利用动态规划来求给定的字符串是不是回文字符串,求给定的字符串是不是回文字符串是固定模式,可以直接套用,
1.i从1到n枚举;
2,j从0开始,满足j+i-1小于n;
3.左边位置l=j,右边位置r=j+i-1;
4.判断s[l]==s[r]&&(l+1>r-1||c[l+1][r-1])是否成立,成立即为回文串,否则不是
二、其次就是求dp[i],dp[i]是前i个字符的最小分割段
1.i从1到n枚举;
2.j从1到i枚举,列举出每段的值;
3.判断是不是回文字符串,是的话执行递归式dp[i]=min(dp[i],dp[j-1]+1)
4.返回结果。
代码
class Solution {
public:
int minCut(string s) {
//判断c[i][j]是不是回文字符串,这是一种固定写法,l是左边位置,r是右边位置
int n=s.size();
vector<vector<bool>>c(n,vector<bool>(n,false));
for(int i=1;i<=n;i++)
{
for(int j=0;j+i-1<n;j++)
{
int l=j,r=j+i-1;
if(s[l]==s[r]&&(l+1>r-1||c[l+1][r-1]))
{
c[l][r]=true;
}
}
}
//dp[i]是前i个字符的最小分割段
vector<int>dp(n+1,INT_MAX/2);
dp[0]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)//j从1枚举到i
{
if(c[j-1][i-1])
{
dp[i]=min(dp[i],dp[j-1]+1);
}
}
}
return dp[n]-1;
}
};