「Manacher算法」学习笔记
觉得这篇文章写得特别劲,插图非常便于理解。
目的:求字符串中的最长回文子串。
算法思想
考虑维护一个数组$r[i]$代表回文半径。回文半径的定义为:对于一个以$i$为回文中心的奇数回文子串,设其为闭区间$[L,R]$,则半径$r=R-i+1$。
$Manacher$算法利用一个类似$DP$的方法来求解这个问题。考虑维护一个目前已经达到的最大的右边界$P$,此右边界对应的对称中心以及左边界分别为$pos$,$P'$。那么分类讨论:
1. $i<P$
此时我们可以找到$i$关于$pos$的对称点$j$。由于$[P',P]$是回文的,所以如果$j$的回文子串不超过边界,那么有$r[i]=r[j]$。
如果$j$超过边界了,说明至少区间内的那一段是能够满足的。因此$r[i] \geq P-i+1$。对于超出的部分,暴力比较(同时更新P)
2. $i \geq P$
此时根据前面的来转移已经没有意义了。直接暴力。
综上我们已经可以求解出所有的$r[i]$了。那么前面所说的回文中心一定要是奇数的长度。能不能把偶数转化为奇数?
答案是在任意两个相邻字符之间插入特殊符号进行间隔(包括开头和结尾)。这样就一定是奇数了。易知对于这种情况,对称中心$i$对应的回文串的长度也就是$r[i]-1$。
刚才是用数学角度在讨论问题,如果代码也按照分类讨论这个标准来实现未免有些冗长。考虑简化问题。
既然$i \geq P$和$j$出界的情况都需要暴力匹配,不如合并到一起?我们发现只要我们确定$r[i]$的最小取值,然后不停增大$r[i]$判断是否成立就好了。当$i \geq P$时,由于未知,最小值固然是1. 而对于$j$出界,最小值固然是$P-i+1$。因此问题就很简单了
$code$
inline void Manacher(){
int j=,P=,pos=,p=,N=,n=strlen(t+);
for(int i = ; i <= n; ++i){
s[++N] = '$';
s[++N] = t[i];
}
s[++N] = '$';
for(int i = ; i < N; ++i){
if(P > i) r[i] = Min(r[pos-(i-pos)], P-i+); else r[i] = ;
while(s[i-r[i]] == s[i+r[i]] && i-r[i]>= && i+r[i]<=N) ++r[i];
if(i+r[i]- > P) P = i+r[i]-, pos = i;
ans = Max(ans, r[i]-);
}
}
「Manacher算法」学习笔记的更多相关文章
- 图解最长回文子串「Manacher 算法」,基础思路感性上的解析
问题描述: 给你一个字符串 s,找到 s 中最长的回文子串. 链接:https://leetcode-cn.com/problems/longest-palindromic-substring 「Ma ...
- Note -「Lagrange 插值」学习笔记
目录 问题引入 思考 Lagrange 插值法 插值过程 代码实现 实际应用 「洛谷 P4781」「模板」拉格朗日插值 「洛谷 P4463」calc 题意简述 数据规模 Solution Step 1 ...
- Note -「动态 DP」学习笔记
目录 「CF 750E」New Year and Old Subsequence 「洛谷 P4719」「模板」"动态 DP" & 动态树分治 「洛谷 P6021」洪水 「S ...
- Note -「单位根反演」学习笔记
\(\mathcal{Preface}\) 单位根反演,顾名思义就是用单位根变换一类式子的形式.有关单位根的基本概念可见我的这篇博客. \(\mathcal{Formula}\) 单位根反演的 ...
- 「AC自动机」学习笔记
AC自动机(Aho-Corasick Automaton),虽然不能够帮你自动AC,但是真的还是非常神奇的一个数据结构.AC自动机用来处理多模式串匹配问题,可以看做是KMP(单模式串匹配问题)的升级版 ...
- 「FHQ Treap」学习笔记
话说天下大事,就像fhq treap —— 分久必合,合久必分 简单讲一讲.非旋treap主要依靠分裂和合并来实现操作.(递归,不维护fa不维护cnt) 合并的前提是两棵树的权值满足一边的最大的比另一 ...
- 「线性基」学习笔记and乱口胡总结
还以为是什么非常高大上的东西花了1h不到就学好了 线性基 线性基可以在\(O(nlogx)\)的时间内计算出\(n\)个数的最大异或和(不需要相邻). 上述中\(x\)表示的最大的数. 如何实现 定义 ...
- 「Link-Cut Tree」学习笔记
Link-Cut Tree,用来解决动态树问题. 宏观上,LCT维护的是森林而非树.因此存在多颗LCT.有点像动态的树剖(链的确定通过$Access$操作),每条链用一颗$splay$维护.$spla ...
- 【Java】「深入理解Java虚拟机」学习笔记(1) - Java语言发展趋势
0.前言 从这篇随笔开始记录Java虚拟机的内容,以前只是对Java的应用,聚焦的是业务,了解的只是语言层面,现在想深入学习一下. 对JVM的学习肯定不是看一遍书就能掌握的,在今后的学习和实践中如果有 ...
随机推荐
- 粮草先行——Android折叠屏开发技术点(一)
最近有关折叠屏产品的新闻层出不穷,各家手机厂商也分别慢慢地亮出了自家的产品.然而市场上的一些APP仍然没有很好地适配这样的设备,显示不正常和应用重启的状况时有发生.因此,我会用接下来的几篇文章来点出有 ...
- 前端javascript如何阻止按下退格键页面回退 但 不阻止文本框使用退格键删除文本
这段代码可以: document.onkeydown = function (e) { e.stopPropagation(); // 阻止事件冒泡传递 e.preventDefault(); // ...
- [转] 以后再有人问你selenium是什么,你就把这篇文章给他
本文转自:https://blog.csdn.net/TestingGDR/article/details/81950593 写在最前面:目前自动化测试并不属于新鲜的事物,或者说自动化测试的各种方法论 ...
- Java开发笔记(八十五)通过字符流读写文件
前面介绍了文件的信息获取.管理操作,以及目录下的文件遍历,那么文件内部数据又是怎样读写的呢?这正是本文所要阐述的内容.File工具固然强大,但它并不能直接读写文件,而要借助于其它工具方能开展读写操作. ...
- 结合JDK源码看设计模式——策略模式
前言: 现在电商已经成为我们生活中不可或缺的购物渠道,同时各大商家会针对不同的时间做出不同的折扣,这在我们看来就是一种营销手段,也是一种策略,今天我们就来讲讲JDK中的策略模式是怎么样的. 一.定义 ...
- 使用cobbler工具实现centos 6,7系统的自动化安装
vmware里面准备两台虚拟机,一台用于安装cobbler服务器,另一台当作测试机使用,cobbler服务器需要两块网卡,一块需要连接外网,需要使用epel源.测试机使用一块仅主机的模式的网卡,注意要 ...
- Nginx配置了解
安装Nginx常用编译选项说明 nginx大部分常用模块,编译时./configure --help查看,以--without开头的都是默认安装. --prefix=PATH 指定nginx的安装目录 ...
- 使用vue-cli快速搭建vue项目
直接上干货...... 步骤: 1.安装node.js:(下载地址:https://nodejs.org/en/download/)安装完成以后,在命令窗口输入node -v 查看node版本. ...
- [转载]编写SQL语句查询出每个各科班分数最高的同学的名字,班级名称,课程名称,分数
[转载]编写SQL语句查询出每个各科班分数最高的同学的名字,班级名称,课程名称,分数 转载自:https://blog.csdn.net/one_money/article/details/56921 ...
- Git - git status - 查看当前仓库状态
索引: 目录索引 参看代码 GitHub: git.txt 一.示例: git status 二.说明: 1."status" 部分 该命令可以查出当前分支文件变更状态, 可以查出 ...