给定一个字符串,返回把str全部切割成回文串的最少切割数。
首先这个题是一个DP题。因为需要动态判断是不是回文串, 再动态计算最小次数。
1 我们开辟一二维数组来存储 从 i-j 是不是回文串
2开辟一个一维数组存储每到一个字符时,最小分割次数
3 动态进行判断
1 每来到一个字符前,向前查询,前文存在的回文串并将其保存。
2 因为当外层第i个字符没有离开前,内层的查询随时可能会更新切割次数,所以内部要及时更新的切割次数。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string s;
cin >> s;
int len = s.size();
vector<int> cnt(len);
vector<vector<int>> ishw(len,vector<int>(len));
//DP思想
for (int i = 1; i < len; ++i) {
cnt[i] = cnt[i-1] + 1;//先得到当前最坏情况
for (int j = i; j >= 0; --j) {
//i-j<2即i==j || i =j+1 否则;只需看外部最大串是不是回文串
if (s[i] == s[j] && (i - j < 2 || ishw[j+1][i-1])) {
ishw[j][i] = 1;
//可能会更新切割次数
//无论当前子串是不是回文串,都需要计算切割次数
cnt[i] = min(j == 0 ? 0 : cnt[j-1] + 1, cnt[i]);//动态衡量
}
}
}
cout << cnt[len-1] << endl;
return 0;
}
力扣 131 题
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: “aab”
输出:
[
[“aa”,“b”],
[“a”,“a”,“b”]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-partitioning
class Solution {
private:
vector<vector<string>> res;
vector<string> tmp;
private:
bool isHW(string& s, int start, int end) {
while(start <= end && s[start] == s[end])
++start,--end;
if(start > end)
return true;
return false;
}
private:
void __partition(string& s, int start)
{
if(s.size() == start){
res.push_back(tmp);
return;
}
for(int i=start; i<s.size(); ++i){
if ( isHW(s, start, i) ){
tmp.push_back(s.substr(start,i-start+1));
__partition(s, i+1);//从切割的末尾开始
tmp.pop_back();
}
}
}
public:
vector<vector<string>> partition(string s) {
res.clear();
tmp.clear();
if(s.size() ==0)
return res;
__partition(s,0);
return res;
}
};