字符串的最长回文串:Manacher’s Algorithm
题目链接:Longest Palindromic Substring
1. 问题描述
Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
2. 各种解法复杂度
- 暴力枚举:O(N^2)
- 记忆化搜索:O(N^2)
- 动态规划:O(N^2)
- Manacher’s Algorithm : O(N)
3. Manacher’s Algorithm
步骤:
字符串里相邻两个字符之间插入一个 # ,开头和结尾也加上 # 。
例如:
Str = “abaaba”, Trans = “#a#b#a#a#b#a#”.
注:Trans 为 transform声明一个数组 P[n] : 其中 n 为 Trans 的长度。P[index] 表示以 index 为中心的最长回文串长度(不包括 index 本身)。例如:
Trans = # a # b # a # a # b # a #
P = 0 1 0 3 0 1 6 1 0 3 0 1 0
声明变量 Cur :表示当前回文串最长的中心的下标(current position),初值为0。
声明变量 Right : 表示以Cur为中心的回文串最右一个字符所处位置。
建立循环,以增量 index 为中心,扩展 index 。也就是检查 index 两边是否相等。如果相等, P[index] 加1。
在循环体中:
- 变量 index :
当前检查的元素的下标。 - 声明变量 index_ mirror :
以Cur为对称轴, index 的对称位置,index_mirror = Cur - ( index - Cur )。 - 在扩展之前检查 Right 是否大于 index :
如果是,那么 P[index] 的值直接赋值为min(R - index, P[index_mirror]);否则P[index] = 0。
- 变量 index :
如果 index + P[index] > Right ,将 Cur 更新为 index 。
找出 P[] 的最大值即是答案。
4. Q&A
为什么要插入 # ?
比如 abba ,以第一个 b 的下标为 index ,如果要比较 index 的回文,那么它就得比较 index 和 index+1
如果插入 #a#b#b#a# ,第一个 b 后面的 # 下标为 index ,则比较 index - 1 和 index + 1 这样代码更清晰,也更好理解。此时 # 的 P[] 值就表示该位置的回文串长度。其他

如上图。由于我们已经检查出 Cur 位置的回文串长度是 9 ,那么 Cur 左右两边的 9 个字符是对称的。如果 index_mirror 的 P[] 值小于等于 R-index 的值(即距离),那么令 P[index] = P[index_mirror] ——对称的性质。为什么要小于他们的距离?因为如果大于他们的距离,例如图中最左边的a,它回文串的范围超出了 Cur 回文串的范围,超出 Cur 范围的对称性是未知的。从图中我们可以看出,在对称右边的a显然 P[] 值跟左边的不相等,它是 1 。此时只能以 index 为中心继续比较(而不是直接令 P[index] = P[index_mirror] ,因为对称性质无法使用)。在检测 index 的最大回文串时,如果检测到 index 的回文串长度最右侧大于 Cur 的最右侧,也就是 Right ,那么将 Cur 更新为 index 。因为如果后面的元素本来可以用更新前 Cur 的对称性,那么更新后的 Cur 的对称性它同样可以用。而 Cur 的更新会使得更后面的元素可以用其对称性。
参考链接:
- Longest Palindromic Substring Part II
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- soulmachine/leetcode -- Github
字符串的最长回文串:Manacher’s Algorithm的更多相关文章
- leetcode.字符串.409最长回文串-Java
1. 具体题目 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串.在构造过程中,请注意区分大小写.比如 "Aa" 不能当做一个回文字符串. 注意: 假设 ...
- Palindrome(最长回文串manacher算法)O(n)
Palindrome Time Limit:15000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit ...
- Manacher模板(O(n)内求最长回文串长度)
转自:https://segmentfault.com/a/1190000008484167 /* 由于回文分为偶回文(比如 bccb)和奇回文(比如 bcacb),而在处理奇偶问题上会比较繁琐,所以 ...
- POJ 3974 回文串-Manacher
题目链接:http://poj.org/problem?id=3974 题意:求出给定字符串的最长回文串长度. 思路:裸的Manacher模板题. #include<iostream> # ...
- 算法笔记_032:最长回文串(Java)
目录 1 问题描述 2 解决方案 2.1 中心扩展法 2.2 Manacher算法 1 问题描述 给定一个字符串,求它的最长回文子串的长度. 2 解决方案 2.1 中心扩展法 此处,首先枚举出回文 ...
- Java实现最长回文串
1 问题描述 给定一个字符串,求它的最长回文子串的长度. 2 解决方案 2.1 中心扩展法 此处,首先枚举出回文串的中心位置,然后,再在该位置上分别向左和向右扩展,记录并更新得到的最长回文串的长度. ...
- Manacher算法 - 求最长回文串的利器
求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...
- 计算字符串的最长回文子串 :Manacher算法介绍
转自: http://www.open-open.com/lib/view/open1419150233417.html Manacher算法 在介绍算法之前,首先介绍一下什么是回文串,所谓回文串,简 ...
- BZOJ.2565.[国家集训队]最长双回文串(Manacher/回文树)
BZOJ 洛谷 求给定串的最长双回文串. \(n\leq10^5\). Manacher: 记\(R_i\)表示以\(i\)位置为结尾的最长回文串长度,\(L_i\)表示以\(i\)开头的最长回文串长 ...
随机推荐
- UML开发工具Rose ralation的破解安装,
UML开发工具Rose ralation的在windows764破解安装, 安装下载还可以参考:http://www.cnblogs.com/leaven/p/3718361.html 跟大家分享怎么 ...
- 数据库 MYSQL操作(一)
数据库 MYSQL操作总结(一) 本文主要介绍一下笔者在使用数据库操作的过程中的一些总结,主要的内容包括一下几个内容: 一.mysql 使用基础(主要包括数据库的安装.基本操作等内容) 二.mysq ...
- SQL Server 实现递归查询
基础数据/表结构 Sql 语句 ;With cte(id,pid,TName)As ( Select id,pid,TName Union All Select B.i ...
- 从PRISM开始学WPF(九)交互(完结)
0x07交互 Notification xaml: <Window x:Class="UsingPopupWindowAction.Views.MainWindow" xml ...
- 20165226 2017-2018-4 《Java程序设计》第6周学习总结
20165226 2017-2018-4 <Java程序设计>第6周学习总结 教材学习内容总结 第八章 常用实用类 string类 并置 两个常量进行并置,得到的仍是常量. public ...
- Docker1.12.6+CentOS7.3 的安装
安装旧版的docker-engine-1.12.6 kubeadm init --api-advertise-addresses=172.16.160.211命令的时候,提示docker版本太新了 一 ...
- 大数据学习总结(5)参考elk技术架构
- JavaScript实现接口的三种经典方式
/* 接口:提供一种说明一个对象应该有哪些方法的手段 js中有三种方式实现接口: 1 注释描述接口 2 属性检测接口 3 鸭式辨型接口 */ /* 1 注释描述接口: 不推荐 优点: 利用注解,给出参 ...
- 项目实战15—企业级堡垒机 jumpserver
本文收录在Linux运维企业架构实战系列 环境准备 系统:CentOS 7 IP:192.168.10.101 关闭selinux 和防火墙 # CentOS $ setenforce # 可以设置配 ...
- scrapy spider官方文档
Spiders Spider类定义了如何爬取某个(或某些)网站.包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item). 换句话说,Spider就是您定义爬取的动作 ...