算法二十五:回文串

描述

给定一个字符串,求出该字符串有多少子串是回文串。

子串:字符串中连续的一段。比如字符串abcd里,bc、abc、a、bcd都是子串。

回文串:字符串倒序写出来和该字符串相同。比如aba,倒序写出来也是aba,故aba是回文串。而abab不是回文串,因为倒过来写是baba。

输入

输入一个字符串。

输出

输出子串是回文串的个数。

样例1输入

abab

样例1输出

6

样例1解释

a bab,a b ab,ab a b

abababab,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;
}
// ================= 代码实现结束 =================




猜你喜欢

转载自blog.csdn.net/wydyd110/article/details/80899332