思路:其实就是枚举第二个回文串的起点和终点,这样子,三个回文串的起点和终点都有了。只要三个区间都是回文即可。
那么我们考虑如何判断一个区间是不是回文串呢?做法有很多,这里n只有2000
所以允许n^2的做法 我们可以枚举回文中点去左右拓展,也可以去区间dp
这里介绍的是区间dp。
dp[i][j]表示第i个字符到第j个字符之间是不是回文串 是的话就为1,不是就为0
l==r 显然dp[l][r]=1
l+1==r dp[l][r]= s[l] == s[r]
其他 即r-l+1>=3 dp[l][r]= (dp[l+1][r-1]) && (s[l] == s[r])
如果会区间dp 方程是很好推出来的
其实一下子想到的方程应该就是r-l+1>=3的情况
但是因为有dp[l+1][r-1]这一步,如果l=r,那么l+1>r-1 所以需要特判
同理当l+1=r时候 也会有l+1>r-1,需要特判
class Solution {
public:
int dp[1<<11][1<<11];
bool checkPartitioning(string s) {
//特判l=r的时候
for(int i=0;i<s.size();i++) dp[i][i]=1;
for(int len=2;len<=s.size();len++){
for(int l=0;l+len-1<s.size();l++){
int r=l+len-1;
//特判l+1=r的时候 此时len=r-l+1=2
if(len==2) dp[l][r]= s[l]==s[r];
else dp[l][r]= (dp[l+1][r-1]) && (s[l]==s[r]);
}
}
//枚举第二个回文串的起点和终点 注意回文串不能空
//所以起点要从第二个字符开始 终点最多到倒数第二个字符
for(int l=1;l<s.size();l++){
for(int r=l;r<s.size()-1;r++){
if(dp[0][l-1] && dp[l][r] && dp[r+1][s.size()-1]){
return 1;
}
}
}
return 0;
}
};