描述
给定一个字符串,求出该字符串有多少子串是回文串。
子串:字符串中连续的一段。比如字符串abcd里,bc、abc、a、bcd都是子串。
回文串:字符串倒序写出来和该字符串相同。比如aba,倒序写出来也是aba,故aba是回文串。而abab不是回文串,因为倒过来写是baba。
输入
输入一个字符串。
输出
输出子串是回文串的个数。
样例1输入
abab
样例1输出
6
样例1解释
a bab,a b ab,ab a babab,abab,abab
提示
[[[https://segmentfault.com/a/1190000003914228]
[这篇文章是求最长的回文串的,那么如何求回文串的数目呢?可以发现manacher算法将每个位置为中心能延展出的最长回文串求出来了,那么这个最长回文串的一半(上取整)就是以该点作为中心的回文串数目。]
[注意答案要用long long。]
扫描二维码关注公众号,回复:
1877576 查看本文章
一. 伪代码
二. 具体实现
#include <bits/stdc++.h>using namespace std;
// ================= 代码实现开始 =================
const int N = 500005;
char s[N * 2];
int len[N * 2];
// 计算str中有多少个回文子串
// 返回值:子串的数目
long long getAnswer(string str) {
int n = str.size();
for(int i = n; i; --i)
s[i << 1] = str[i-1], s[i << 1 | 1] = 0;
n = n << 1 | 1;
s[1] = 0,s[0] = 1,s[n+1] = 2;
int cur = 1;
long long ans =0;
for(int i=2; i<=n; ++i){
int &now = len[i], pos = (cur << 1) -i;
now = max(min(len[pos],cur+len[cur]-i),0);
while(s[i-now-1] == s[i + now +1])
++now;
if(i + now > cur +len[cur])
cur = i;
ans += (now + 1) >> 1;
}
return ans;
}
// ================= 代码实现结束 =================