题目
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文。
返回符合要求的 最少分割次数 。
示例 1:
输入:s = “aab”
输出:1
解释:只需一次分割就可将 s 分割成 [“aa”,“b”] 这样两个回文子串。
示例 2:
输入:s = “a”
输出:0
示例 3:
输入:s = “ab”
输出:1提示:
1 <= s.length <= 2000 s 仅由小写英文字母组成
解答
思路
- 按照昨天的思路,首先用第一个动态规划,将整个组合变成二维数组,并且标记其是否为回文字串
- 按照动态规划解题(背包问题),如果需要目前最小的切割次数,则依次进行分割,其字串中的回文串加上当前切割的1次,并且得到递推式:
代码
class Solution {
public:
int minCut(string s) {
int n = s.size();
//第一次动态规划
vector<vector<int>> g(n,vector<int>(n,true));
for(int i=n-1;i>=0;--i){
for(int j=i+1;j<n;++j)
g[i][j] = (s[i]==s[j])&&g[i+1][j-1];
}
//第二次动态规划
vector<int> f(n,INT_MAX);
for(int i=0;i<n;++i){
//如果为一个字符串,不需要分割
if(g[0][i])
f[i] = 0;
else //找到所有为回文字串,并且加1后,与当前值取小者
for(int j=0;j<i;++j)
if(g[j+1][i])
f[i] = min(f[i],f[j]+1);
}
return f[n - 1];
}
};