Manacher算法

算法描述与证明

cpp 复制代码
for (int i = 1; i <= m; i++) { // 遍历预处理后的字符串t
    p[i] = 1;                 // 初始化最小回文半径为1(单个字符)
    if (maxid > i)            // 如果i在当前最右回文边界内
        p[i] = min(p[2 * id - i], maxid - i); // 利用对称性快速确定下限
    
    // 暴力扩展回文半径
    while (t[i - p[i]] == t[i + p[i]]) 
        p[i]++;               // 若两侧字符相等,半径+1
    
    // 更新最右回文边界及中心
    if (i + p[i] > maxid) {
        id = i;
        maxid = i + p[i];
    }
}

部分代码分析

cpp 复制代码
while(t[i-p[i]] == t[i+p[i]])
    p[i]++;

这段代码是看在当前以 i 为中心(如果超出了)最大范围外的左边和右边是否相等,如果相等说明可以进一步扩展,将当前回文半径加一。

cpp 复制代码
if(maxid > i)
    p[i] = min(p[2 * id - i], maxid - i);

这段代码是,如果当前点在当前最大回文子串的范围内,找当前点的以当前最大回文子串中心点的对称点(以当前最大回文子串中心点折过去所对应的点)和当前点到当前最大回文子串右边界的距离的最小值。因为串对称过来以后超过当前最大回文子串右边界的话,超出的部分就不能对称过来了(不能保证左侧超出的部分和右侧超出的部分相同)。所以要取两者最小值。

完整流程

步骤 操作 目的
1 预处理字符串(插入#和哨兵) 统一奇偶回文为奇数长度
2 初始化p[i]=1 每个字符至少自身是回文
3 利用对称性快速确定下限p[i] = min(p[j], maxid-i) 跳过重复比较,优化效率
4 暴力扩展while(...) p[i]++ 验证并扩大回文半径
5 更新maxidid 维护当前最右回文边界信息
相关推荐
宝贝儿好几秒前
【LLM】第一章:分词算法BPE、WordPiece、Unigram、分词工具jieba
人工智能·python·深度学习·神经网络·算法·语言模型·自然语言处理
渡我白衣2 分钟前
运筹帷幄——在线学习与实时预测系统
人工智能·深度学习·神经网络·学习·算法·机器学习·caffe
colus_SEU3 分钟前
SVM 的终极视角:合页损失函数 (Hinge Loss) 与正则化
算法·机器学习·支持向量机
汀、人工智能4 分钟前
[特殊字符] 第71课:爬楼梯
数据结构·算法·数据库架构·图论·bfs·爬楼梯
MicroTech20255 分钟前
微算法科技(NASDAQ :MLGO)量子启发式算法与CNN、Transformer结合,实现端到端彩色图像分割
科技·算法·启发式算法
X journey6 分钟前
机器学习进阶(14):交叉验证
人工智能·算法·机器学习
lolo大魔王11 分钟前
Go语言的循环语句、判断语句、通道选择语句
开发语言·算法·golang
念恒123063 小时前
继承(下) (Inheritance)
c++
海清河晏1114 小时前
数据结构 | 单循环链表
数据结构·算法·链表
H Journey4 小时前
C++之 CMake、CMakeLists.txt、Makefile
开发语言·c++·makefile·cmake