给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回符合要求的最少分割次数。
示例:
输入: “aab”
输出: 1
解释: 进行一次分割就可将 s 分割成 [“aa”,“b”] 这样两个回文子串。
/*class Solution {
private:
bool isPalindStr(string s)
{
if(s.length() == 1) return true;
int len = s.length();
for(int i = 0; i < len/2; i++)
{
if(s[i] != s[len-i-1]) return false;
}
return true;
}
void dfs(string s, int left, int step, int &minStep)
{
if(left >= s.length())
{
minStep = min(step-1, minStep); //注意此处是step-1
return;
}
for(int right = left; right < s.length(); right++)
{
string strTmp = s.substr(left, right-left+1);
if(isPalindStr(strTmp))
{
dfs(s, right+1, step+1, minStep);
}
}
}
public:
int minCut(string s) {
if(s.length() <= 1) return 0;
int minStep = s.length()-1;
dfs(s, 0, 0, minStep);
return minStep; //递归存在超时
}
};*/
class Solution {
public:
int minCut(string s) {
if(s.length() <= 1) return 0;
int len = s.length();
vector<vector<bool>> area(len, vector<bool>(len, false)); //辅助矩阵判断回文串
vector<int> dp(len, len-1); //dp[i]表示0--i个字符用dp[i]次分割可构成回文串,注意初始化值
for(int i = 0; i < len; i++)
{
for(int j = 0; j <= i; j++)
{
if((s[j] == s[i]) && ((i - j <= 2) || (area[j+1][i-1])))
{
area[j][i] = true;
dp[i] = (j == 0) ? 0 : min(dp[i], dp[j-1]+1); //j==0表示0-i个字符是回文串,此时分割次数是0
}
}
}
return dp[len-1];
}
};
提供了两种解决方式,递归法会超时,推荐用动态规划