浅谈Manacher算法
Manacher
manacher是一种\(O(n)\)求最长回文子串的算法,俗称马拉车(滑稽)
直接步入正题
首先可以知道的是:每一个回文串都有自己的对称中心,相应的也有自己的最大延伸长度(可以称之为“半径”)
我们设\(rad[i]\)表示以\(i\)为中心的回文子串的半径,那么只需要知道所有的\(rad[i]\)就可以求出最长回文子串了
从\(1\)到\(n\)枚举\(i\),求解\(rad[i]\)
设当前已经求到了\(rad[k]\),设前\(k-1\)个数中\(rad[i]+i\)(即右端点)最大的数为\(mid\),令\(r=mid+rad[mid]\)
那么可以证明一个点\(i\)关于\(mid\)的对称点是\(2\times mid-i\)(两点距离公式)
opt1:如果\(k\leq r\)

方便起见,令\(j=2\times mid-k\)
1.若\(j-rad[j]>mid-rad[mid]\),即以\(j\)点为中心的最长回文子串的左端点在以\(mid\)为中心的最长回文子串的左端点右边,则\(rad[i]\)可以直接由\(rad[j]\)转移过来(因为\(2\times mid-r\)$mid$和$mid$\(r\)是对称的,所以\(k\)的半径和\(j\)的半径是一样的),即\(rad[i]=rad[j]\)
2.若\(j-rad[j]\leq mid-rad[mid]\),则\(rad[k]\)至少是\(r-k\)。接下来再暴力延伸,顺便更新\(mid\)和\(r\)
opt2:如果\(k>r\)
直接暴力延伸,顺便更新\(mid\)和\(r\)
可以发现每次暴力延伸的时候,暴力延伸多少,\(r\)也会变化多少,且\(r\)是递增的且不超过\(n\)的数
关于复杂度:
由于每一个字符最多只会被遍历一次,所以复杂度是\(O(n)\)的
实现细节:
1.由于长度为偶数的回文串对称中心并不能实际找到,所以在两个字符之间插入#。这样不会影响答案,并且可以解决这个问题
2.对于不同情况的相似之处可以合并到一起来降低码量,如op1.1的直接转移和opt1.2的转移等
3.不要忘了更新\(mid\)和\(r\)
4.注意下标
代码:
#include<bits/stdc++.h>
using namespace std;
char cString[22000005];
int iRad[22000005];
int iLen,iAns;
void read()
{
char c = getchar();
cString[0] = '|', cString[++iLen] = '#';
while(c < 'a' || c > 'z') c = getchar();
while(c >= 'a'&& c <= 'z') cString[++iLen] = c, cString[++iLen] = '#', c = getchar();
}
int main()
{
read();//读入
for(int i = 1, mid = 0, r = 0; i <= iLen; i++)
{
if(i <= r) iRad[i] = min(iRad[mid * 2 - i], r - i + 1);//opt1
while(cString[i - iRad[i]] == cString[i + iRad[i]]) ++iRad[i];//opt1.2,opt2 尝试暴力延伸
if(i + iRad[i] > r) r = i + iRad[i] - 1, mid = i;//更新mid和r
if(iRad[i] > iAns) iAns = iRad[i];//更新答案
}
printf("%d", iAns-1);
}
浅谈Manacher算法的更多相关文章
- 浅谈Manacher算法与扩展KMP之间的联系
首先,在谈到Manacher算法之前,我们先来看一个小问题:给定一个字符串S,求该字符串的最长回文子串的长度.对于该问题的求解.网上解法颇多.时间复杂度也不尽同样,这里列述几种常见的解法. 解法一 ...
- 【字符串算法2】浅谈Manacher算法
[字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述 字符串算法2:Manacher算法 问题:给出字符串S(限制见后)求出最 ...
- 浅谈分词算法(5)基于字的分词方法(bi-LSTM)
目录 前言 目录 循环神经网络 基于LSTM的分词 Embedding 数据预处理 模型 如何添加用户词典 前言 很早便规划的浅谈分词算法,总共分为了五个部分,想聊聊自己在各种场景中使用到的分词方法做 ...
- 浅谈分词算法(4)基于字的分词方法(CRF)
目录 前言 目录 条件随机场(conditional random field CRF) 核心点 线性链条件随机场 简化形式 CRF分词 CRF VS HMM 代码实现 训练代码 实验结果 参考文献 ...
- 浅谈分词算法(3)基于字的分词方法(HMM)
目录 前言 目录 隐马尔可夫模型(Hidden Markov Model,HMM) HMM分词 两个假设 Viterbi算法 代码实现 实现效果 完整代码 参考文献 前言 在浅谈分词算法(1)分词中的 ...
- 浅谈分词算法基于字的分词方法(HMM)
前言 在浅谈分词算法(1)分词中的基本问题我们讨论过基于词典的分词和基于字的分词两大类,在浅谈分词算法(2)基于词典的分词方法文中我们利用n-gram实现了基于词典的分词方法.在(1)中,我们也讨论了 ...
- 【字符串算法3】浅谈KMP算法
[字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述 [字符串算法3]KMP算法 Part1 理解KMP的精髓和思想 其实KM ...
- 浅谈Manacher
\(Manacher\)是由一个叫做\(Manacher\)的人发明的能在\(O(n)\)时间内找出一个字符串长度最长的回文子串的算法. 由于偶回文串形如\(abba\)这样的不好找对称中心,所以我们 ...
- 浅谈Tarjan算法
从这里开始 预备知识 两个数组 Tarjan 算法的应用 求割点和割边 求点-双连通分量 求边-双连通分量 求强连通分量 预备知识 设无向图$G_{0} = (V_{0}, E_{0})$,其中$V_ ...
随机推荐
- 特产网站自适应CSS
下面是一个特产网站自适应CSS,这个特产自适应CSS通过屏幕宽度大小来进行适应的,而不是根据UA来判断,就加快了判断的速度,所以速度很快 中国特产站排名还是很好的,特别是手机端 li { list-s ...
- ORACLE (BLOB、CLOB、NCLOB、BFILE)
LOB类型 内置的LOB数据类型包括BLOB.CLOB.NCLOB.BFILE(外部存储)的大型化和非结构化数据,如文本.图像.视屏.空间数据存储.BLOB.CLOB.NCLOB类型 4.1 CLOB ...
- commons Collections4 MultiMap
MultiMap<String, Integer> multiMap = new MultiValueMap<>(); multiMap.put("A", ...
- 2019-11-29-asp-dotnet-core-通过图片统计-csdn-用户访问
title author date CreateTime categories asp dotnet core 通过图片统计 csdn 用户访问 lindexi 2019-11-29 08:26:58 ...
- poj 1007 DNA sorting (qsort)
DNA Sorting Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 95209 Accepted: 38311 Des ...
- hiho #1043 : 完全背包
01背包和完全背包解析 在上一节的01背包中,每种物品只能使用一次. 初始化j=V,逆序推能够保证 dp[v-c[i]] 保存的是状态是 dp[i-1][v-c[i]] ,也就是每个物品只被使用了一次 ...
- zabbix-server一键部署
最近想写一个zabbix脚本,自己尝试几次,能够实现,但是太糙了,在github上发现一个很好,谢谢作者脚本作者:火星小刘 web:www.huoxingxiaoliu.com email:xtlyk ...
- chromedriver.exe,自动化web, 安装谷歌驱动,以及可能遇到的坑
1.下载谷歌驱动:chromedriver.exe http://chromedriver.storage.googleapis.com/index.html (下载驱动的链接) 2.把下载的chro ...
- 29. ClustrixDB 分布式架构/并发控制
介绍 ClustrixDB使用多版本并发控制(MVCC)和2阶段锁(2PL)的组合来支持混合的读写工作负载.在我们的系统中,读取器享受无锁快照隔离,而写入器使用2PL来管理冲突.并发控制的组合意味着读 ...
- jquery password选择器 语法
jquery password选择器 语法 作用::password 选择器选取类型为 password 的 <input> 元素.大理石平台精度等级 语法:$(":passwo ...