法一:中心扩展法
合并奇数长度和偶数长度回文子串的情况
时间复杂度o(n^2),空间复杂度o(1)
法二:Manacher算法
class Solution {
public:
int countSubstrings(string s) {
if(0){
//中心拓展,时间复杂度o(n^2),空间复杂度o(1)
int n=s.size();
int ans=0;
for(int i=0;i<2*n+1;i++){
int l=i/2,r=i/2+i%2;
while(l>=0&&r<n&&s[l]==s[r]){
--l;
++r;
++ans;
}
}
return ans;
}else if(1){
//manacher算法,时间复杂度o(n),空间复杂度o(n)
//开头位置‘$’
string t="$#";
for(auto c:s){
t+=c;
t+='#';
}
int n=t.size();
//结束位置'!',不让下标越界!
t+='!';
vector<int> p(n);
int iM=0,rM=0,ans=0;
for(int i=1;i<n;i++){
p[i]=i>rM?1:min(p[2*iM-i],rM-i+1);
while(t[i+p[i]]==t[i-p[i]]) ++p[i];
if(i+p[i]-1>rM){
iM=i;
rM=i+p[i]-1;
}
ans+=(p[i]/2);
}
return ans;
}
}
};