给定一个字符串s,将s分割成一些子串,使每个子串都是回文。
返回s符合要求的的最少分割次数。
样例
比如,给出字符串s = "aab",
返回 1, 因为进行一次分割可以将字符串s分割成["aa","b"]这样两个回文子串
点题:一定要小心又小心,不要在最简单的地方翻船!!!!! i++, j--
class Solution {
public:
/**
* @param s a string
* @return an integer
*/
int minCut(string s) {
// write your code here
if (s.size() == 0) {
return 0;
}
vector<int> dp(s.size(), 0);
for (int i = 1; i < s.size(); i++) {
if (IsTarget(s.substr(0, i + 1))) {
dp[i] = 0;
continue;
}
dp[i] = i;
for (int j = i; j > 0; j--) {
if (IsTarget(s.substr(j, i - j + 1))) {
dp[i] = min(dp[i], dp[j - 1] + 1);
}
}
}
return dp[s.size() - 1];
}
bool IsTarget(const string& s) {
if (s.size() == 1) {
return true;
}
int i = 0;
int j = s.size() - 1;
while (i < j) {
if (s[i++] != s[j--]) {
return false;
}
}
return true;
}
};
解法2:减少判断是否是回文的运算量
class Solution {
public:
int minCut(string s) {
if (s.size() == 0) {
return 0;
}
vector<int> dp(s.size(), 0);
vector<vector<bool>> status(s.size(), vector<bool>(s.size(), false));
for (int i = 0; i < s.size(); i++) {
status[i][i] = true;
if (i + 1 < s.size() && s[i] == s[i + 1]) {
status[i][i + 1] = true;
}
}
for (int i = 1; i < s.size(); i++) {
if (i + 1 > 2) {
status[0][i] = status[1][i - 1] && s[0] == s[i];
}
if (status[0][i]) {
continue;
}
dp[i] = i;
for (int j = i; j > 0; j--) {
if (i - j + 1 > 2) {
status[j][i] = status[j + 1][i - 1] && s[j] == s[i];
}
if (status[j][i]) {
dp[i] = min(dp[i], dp[j - 1] + 1);
}
}
}
return dp[s.size() - 1];
}
};