【学习笔记】字符串回文算法

Page Views Count

Manacher#

非线性的求回文算法#

  • O(n2):枚举每个位置作为中心,不断向两侧扩展。

  • O(nlogn):二分+哈希。

线性的求回文算法#

维护一个回文串 [l,r] 为当前右端点最靠右的回文串,设当前枚举位置 ii[l,r] 回文中心对称的位置 j=l+ri

由于 j 的最长回文半径已经处理过,因此当 ir 时,分别以 ij 为中心的回文串中的部分(在 [l,r] 中的部分)同样对称;剩余情况则从 1 开始。

按照暴力的方法扩展,更新 [l,r],这里由于 r 只增不减,所以总扩展次数是 O(n) 的。

回文分奇数偶数两种,统一处理一般插入分隔符。

然而事实上求回文串的的线性算法不会优化算法瓶颈。(对数复杂度中二分与数据结构中的修改是并列的)

点击查看代码
int n;
char s[maxn<<1];
int d[maxn<<1];
int ans;
inline void Manacher(){
    for(int i=1,l=0,r=-1;i<=2*n+1;++i){
        int j=l+r-i,k;
        if(i>r) k=1;
        else k=min(d[j],r-i+1);
        while(i-k>=1&&i+k<=2*n+1&&s[i-k]==s[i+k]) ++k;
        d[i]=k;
        ans=max(ans,(d[i]*2-1)/2);
        if(i+k-1>r) l=i-k+1,r=i+k-1;
    }
}
int main(){
    scanf("%s",s+1);
    n=strlen(s+1);
    for(int i=n;i>=1;--i) s[i*2]=s[i];
    for(int i=0;i<=n;++i) s[i*2+1]='#';
    Manacher();
    printf("%d\n",ans);
    return 0;
}

回文自动机 Palindrome Automaton#

构建#

与回文有关且同样存在后缀指针的一种自动机。

由于回文串分奇数偶数,自动机存在两个根:奇根 1 和偶跟 0,需要维护回文串长 len(u) 和最长回文真后缀指针 fail(u)

构建的实际过程比较好理解,在上一个节点的基础上增量,一直跳 fail 指针直到可以前后各扩展一个位置(为了方便计算奇根的长度设为 1),如果已经有对应的转移,无需再修改;如果需要新建节点,就要再处理一下两个指针,按照同样方法就可以。设刚刚找到可以扩展的位置 u,那么再寻找到的 fail 指针位置关于 u 的最长回文串回文中心对称之后,显然是已经出现过的,也就是不需要再新建节点。

将上述过程扩展,也就是在一个字符串结尾增加一个字符,之后最长的回文后缀可能是新增加的,换言之,一个字符串的本质不同回文子串只有不超过 |s| 个。

点击查看代码
char s[maxn];
struct PalindromeAutomaton{
    int tot,last;
    int ch[maxn][26];
    int len[maxn],fail[maxn];
    PalindromeAutomaton(){
        tot=1,last=1;
        len[0]=0,fail[0]=1;
        len[1]=-1,fail[1]=1;
    }
    int get_fail(int u,int pos){
        while(s[pos-len[u]-1]!=s[pos]) u=fail[u];
        return u;
    }
    void extend(int pos){
        int c=s[pos]-'a';
        int u=get_fail(last,pos);
        if(!ch[u][c]){
            int f=get_fail(fail[u],pos);
            ++tot;
            len[tot]=len[u]+2,fail[tot]=ch[f][c];
            ch[u][c]=tot;
        }
        last=ch[u][c];
    }
}PAM;

参考资料#

Manacher#

回文自动机 Palindrome Automaton#

  • OI Wiki

作者:SoyTony

出处:https://www.cnblogs.com/SoyTony/p/Learning_Notes_about_String_Palindrome_Algorithms.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   SoyTony  阅读(149)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示