【算法】Manacher(马拉车)算法

manacher(马拉车)算法详解+例题一道【bzoj3790】【神奇项链】 [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=39091399 (优快云好像有bug,不知道为什么存的草稿覆盖了之前的博客>.<,以后再也不存线上草稿了)昨天学了马拉车(manacher)算法,今天做了一道例题。虽然并不难,但还是写一写博客,即为民服务,又加深自己的理解。manacher是高效处理回文 阅读详情

原jekyll 2019-09-07

Manacher’s Alogrithm,中文名叫马拉车算法,是一位叫Manacher的人在1975年提出的一种算法,解决的问题是求最长回文子串,算法的神奇之处就在于将时间复杂度精进到了O(N)。还记得在两年前的四省赛中,有一道关于回文的题,题解就是用马拉车算法做解的,然而我们没有做出来。

01 由来

在求解最长回文子串时,一般的思路是以当前字符为中心向两边扩展寻找回文,但复杂度是O(N^2),那能不能将复杂度降低到线性?马拉车算法就是为此诞生的。

02 预处理

为了在处理字符串的时候不需要为字符串长度是奇数还是偶数而分别考虑,将对原始字符串进行处理,在每一个字符的左右两边都加上特殊字符(肯定不存在原始字符串中的字符),让字符串变成一个长度为奇数的字符串。如: abba --> #a#b#b#a#

03 计算最长回文子串长度

以字符串"arddrb"为例,将预处理后的新字符串"#a#r#d#d#r#b#",作为一个新的字符串arr,定义一个辅助数组Len,Len的长度与arr等长,用Len[i]来表示以arr[i]字符为中心的最长回文半径。
在等待Len数组计算出来之后,取Len数组中值最大的数所对应的下标,就是arr字符串中的所对应的字符为中心的回文串的半径,Len数组有一个特点:Len[i]-1的值,就是原字符串中该以该字符为中心的回文串的长度。以下为i、arr、Len对应的值

i     0 1 2 3 4 5 6 7 8 9 10 11 12
arr   # a # r # d # d # r #  b  #
Len   1 2 1 2 1 2 5 2 1 2 1  2  1

04 计算回文子串起始索引

取出Len数组中最大的值的索引i后,应该如何由得到原字符串该字符的索引呢?继续以str=“arddrb"为例,有arr=”#a#r#d#d#r#b#",Len[6]=5,发现6-Len(6)=1,即i-Len[i]就是arr[i]字符在原始字符串中的下标。但以str=“aba"为例,arr=”#a#b#a#",Len[3]=4,3-Len[3]=-1,所以str[-1]将会溢出。为了避免奇回文溢出,所以在arr的首尾再分别添加一个特殊字符,如下

i     0 1 2 3 4 5 6 7 8 9 10
arr   @ # c # a # b # a # $
Len   1 1 2 1 2 1 4 1 2 1 1

可以看出,对于b字符来说,6-Len(6)=2,可以得到最长回文子串的起始索引为(i-Len(i))/2。

05 计算Len数组

第三步和第四部都是以Len数组计算完成为前提来进行的,计算Len数组就是马拉车算法的主要工作了,还是以"arddrb"为例,

i     0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
arr   @ # a # r # d # d # r  #  b  #  $
Len   1 1 2 1 2 1 2 5 2 1 2  1  2  1  1

定义两个变量Mi和R,Mi是所有回文子串中,能延伸到最右端位置的那个回文子串的中心点位置,R是该回文串能延伸到最右端的位置。

当i=7时,Len[i]=5,在以位置7位中心点的回文子串中,该回文串的右边界是位置12。

当i=12时,Len[i]=2,在以位置12位中心点的回文子串中,该回文串的右边界是位置14。

所以可以得到,R=Len[i]+i

具体编程时,从左往右计算数组Len,需要分以下情况

1) 当i <= R时,首先毫无疑问Len数组中i点之前的对应的值已经求出来了,利用回文的特点,只要找到i关于Mi点对称的点j,j=Mi* 2-i,i、j在以Mi为中心的回文串的范围内[L, R]:

  • 如果Len[j] < R-i(同样是L到j的距离),说明以j为中心的回文串没有超出范围[L, R],所以,Len[i] = Len(j),如下图
    image
  • 如果Len[j] >= R-i,即j为中心的回文串的最左端超过L,如下图所示,所以Len[i] = Len[j]是不成立的,有回文串的特性可知,Len[i] 至少等于R-i,至于是否大于R-i,那还得需要从R+1开始一一匹配,直到失配为止,从而更新R和对应的中心点Mi以及Len[i]。
    image

2) 当i > R时,如下图,这种情况没法用到回文串的特性,只能老实地去一一匹配。
image

代码如下(以leetcode第5题为例)

public String longestPalindrome(String s) {
	int mi = 0;
	int right = 0;
	int maxlength = 0;
	int maxpoint = 0;
	String temp = "@#";
	for(int i = 0; i < s.length(); i++){
		temp += s.charAt(i);
		temp += "#";
	}
	temp += "*";
	int[] p = new int[temp.length()];
	for(int i = 0; i < temp.length(); i++){
		p[i] = 0;
	}
	for(int i = 1; i < temp.length()-1; i++){
		p[i] = right > i? Math.min(p[2*mi-i], right - i) : 1;
		while(temp.charAt(i+p[i]) == temp.charAt(i-p[i])){
			p[i]++;
		}
		if(i + p[i] > right){
			right = i + p[i];
			mi = i;
		}
		if(maxlength < p[i]){
			maxlength = p[i];
			maxpoint = i;
		}
	}
	//(maxpoint - maxlength)/2为最长回文数的起始点,maxlength为最长回文数的长度
	return s.substring((maxpoint - maxlength)/2, (maxpoint - maxlength)/2 + maxlength - 1);
}

理解p[i] = right > i? Math.min(p[2* mi-i], right - i) : 1;就将manacher理解的差不多了。

马拉车算法(C/C++) 是一种用于在字符串中查找最长回文子串的线性时间复杂度算法。该算法由Udi Manacher在1980年代提出,因此得名。它的核心思想是利用已知的回文信息来减少不必要的比较,从而提高效率。 阅读详情

相关推荐

C++(STL) - Alogrithm头文件

C++ STL:C++ Standard Template Library(C++标准模板库) ⒈ 数组排序 sort + 数组倒置 reverse #include <iostream> #include<algorithm> using namespace std; bool compare(int a,int b){ return a>b; } /...

⚡ 1346

Manacher (马拉车算法)

Manacher (马拉车算法) 的介绍 中心扩展算法 —— 优化 —— 马拉车 P3805 模板manacher 算法 P1659 [国家集训队]拉拉队排练 P4555 [国家集训队]最长双回文串

日常记录,挨打要立正! 2万+

[Arcgis插件分享]--在线地图、地图配色

插件介绍:MapOnline在线地图插件是一套由北京茗禾科技有限公司研发的基于ArcGIS的插件工具,用户通过注册“数据禾”网站,即可使用MapOnline实现各种在线地图资源的集成加载,以及网站共享资源的免费下载。包括:谷歌地图、谷歌地球(无偏)、高德地图、天地图(无偏)、搜搜地图、必应地图(无偏)、OSM地图(无偏)、Esri影像(无偏),以及自定义切片的加载。⑤在Arcmap操作窗口上方的菜单栏右键,调用「MapOnlinev1.2.4」②双击安装文件夹内的「MapOnline.esriAddIn」

weixin_59101151的博客 5767

Manacher算法(马拉车算法)

Manacher算法,又叫“马拉车”算法,可以在时间复杂度为O(n)的情况下求解一个字符串的最长回文子串长度的问题。

诸君拔剑吧. 4280

摄像机实时接入分析平台视频分析网关AI智能分析智慧营业厅方案

通过智能化的改造,可以提高营业厅的运营效率,降低运营成本,同时提升客户体验和安全保障。

EasyDarwin开源社区技术博客 703

BPMN2.0规范及流程引擎选型方案

本文主要简明扼要的介绍了BPMN2.0规范的内容,可让读者快速度的了解BPMN2.0所涵盖的主要内容和图形样式。也较为详细的阐述了如何绘制标准的流程图,以及在软件层面中如何实现业务流程功能,和技术选型。

比特桃 1万+

马拉车(Manacher)算法

马拉车算法与KMP算法都是解决字符串问题的经典算法,为什么把它们俩个放在一起呢?这是因为它们的思想都是用前面已知的信息去更新后面的信息。

qq_42376883的博客 1571

MySQL安装配置教程(超级详细)

一、 下载MySQL Mysql官网下载地址:MySQL :: Download MySQL Installer (Archived Versions) 1. 选择要安装的版本,本篇文章选择的是5.7.31版本,点击Download下载 正在上传…重新上传取消 二、 安装MySQL 1. 选择设置类型双击运行mysql-installer-community-5.7.31.0.msi 这里选择是自定义安装,所以直接选择“Custom”,点击“Next” “Developer Default”是

m0_67322837的博客 5万+

浅析 manacher(马拉车)算法

文章介绍了Manacher算法的核心思想,给出了实现代码和复杂度分析,并推荐了两道练习题供读者巩固。

doooge_awa的博客 788

群晖Docker安装GitLab

external_url ‘http://lanweixia.synology.me’ 这种情况访问页面的时候加上端口没问题,但是会导致http的克隆地址没有端口。external_url ‘http://lanweixia.synology.me:8000’ 加端口的话,又会导致页面访问不了,Gitlab也一直处于启动状态。​ 完成以后修改docke—>gitlab—>config---->gitlab.rb。就是上面改的端口(docker的端口)首次进入,会设置密码,这个密码就是用户名。

Lim的博客 9110

【系统分析师】核心考点:100个高频知识点汇总

本文系统梳理了系统分析师考试的11大领域高频考点,重点解析了计算机硬件与体系结构的7个核心知识点:计算机五大部件(CPU/存储器/总线等)、校验码类型(奇偶/海明/CRC)、CISC与RISC指令系统对比、总线分类与特性、RAID磁盘阵列级别、流水线技术原理及Flynn系统分类法。内容涵盖硬件组成、数据校验、指令架构、存储技术等关键概念,通过表格对比和公式说明,为考生提供结构化的知识框架与备考重点。

数据知道的博客 5571

Manacher(马拉车)算法——杨子曰算法

Manacher(马拉车)算法——杨子曰算法 马拉车?中华汉字真是博大精深…… 今天我们曰的算法只能干一件事情——求一个字符串的最长回文子串(神马是回文子串就不用我说了吧) 首先我们来想一想大暴力怎么做 “我知道!枚举子串的头,枚举子串的尾,再暴力判断这个串是不是回文串,复杂度O(n3)” 杨子曰:“呃……太暴力了,能不能稍稍优化一下” 我们枚举回文字串的中心,然后向两边延伸,比较是否对称,一...

杨子曰:代码是神奇的 289

ECU诊断功能测试:从理论到实践

ECU诊断功能是指通过特定的诊断协议与ECU进行通信,以获取ECU的状态信息、故障码、数据流等,并执行特定的诊断操作。诊断功能的主要目的是帮助开发人员和维修人员快速定位和解决ECU中的问题,确保车辆的安全性和可靠性。UDS协议是ISO 14229标准的一部分,定义了一系列的诊断服务,如读取故障码、清除故障码、读取数据流等。UDS协议基于CAN(Controller Area Network)总线,具有较高的灵活性和扩展性。读取故障码是诊断功能中最基本的操作之一。通过读取故障码,可以快速定位ECU中的问题。

闲人编程的博客 1807

回文子串马拉车(Manacher)算法

1 介绍 给定一个字符串,要求输出该字符串所有可以构成回文串的子串 2 暴力计算 2.1 思想 对于每个位置,我们从当前位置向左右两侧扩展,依次比对对称位置上的字符,知道字符不匹配为止,就构成了一个回文子串。 我们需要考虑回文子串的长度是奇数还是偶数 (1)当回文子串长度为奇数时: 例如:abcba 我们只需要从c位置向左右两侧扩展即可 (2)当回文子串长度为偶数时: 例如:abba 我们无法找到中间位置,因此上述从中间位置向两侧扩展无法实行 因此,我们需要对输入的字符串进行加工 2.2 字符串的加工 2.

Lhw_666的博客 853

微信小程序推广策略,打开小程序领域流量大门

本文旨在为小程序开发者、运营者和企业主提供一套完整的微信小程序推广策略体系,帮助他们在竞争激烈的小程序生态中获得更多流量和用户。内容涵盖从0到1的冷启动策略,到成熟期的增长技巧。本文将首先介绍小程序的基础推广设置,然后深入探讨各种流量获取渠道,接着分析数据驱动的优化方法,最后展望未来发展趋势。小程序:无需下载安装即可使用的应用,运行在微信生态内:独立访客数:页面浏览量转化率:完成目标行为的用户比例留存率:用户在一定时间后仍活跃的比例自然流量获取:通过优化搜索、完善资料等方式获得基础流量社交裂变。

小程序开发 1031

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Manacher马拉车算法Java简洁代码+面试题目

Manacher马拉车算法 基本概念 添加字符#,可以解决字符串长度奇偶数问题。例如: 字符串:11311 表格第二行为,以当前字符为中心的最长回文子串长度,除以2则为在原字符串中的回文子串长度。例如:11/2=5,表示中心为3时最长回文长度为5。 # 1 # 1 # 3 # 1 # 1 # 1 3 5 3 1 11 1 3 5 3 1 回文半径数组:以每个字符为中心,能...

Smooklazz~的博客 445

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

马年“码”上发力:用Manacher“马拉车”算法,拉平最长回文难题

今年是马年, 我来分享一个与 “马” 有关的算法, Manacher(马拉车)。 前言 Manacher(马拉车)算法 问题: 1.相关概念引入 2.中心扩展算法 算法原理 预处理 3.Manacher算法 概念引入 分类讨论(核心) 4.算法模板 结尾

燃于AC之乐的博客 1407

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Manacher(马拉车)算法详解

算法的主要思路是维护一个最右回文子串,利用该区间的对称性,计算当前遍历位置为中心的回文半径,回文半径就是从中心(如果为奇回文串,就包含中心位置)到回文串一端的距离。我们可以再每个字符之间加入特殊字符,奇回文串的中心不变,偶回文串的中心就变成了特殊字符。还有另一种枚举的方法,是中心扩散法,利用了回文串的对称性,枚举每一个字符,然后从中心向两边比较,时间复杂度也为。求最长回文子串的方法,最容易想到的就是暴力枚举,将所有的回文子串都找出来,然后找做大的,时间复杂度就相当高了。,回文串可以分为奇回文串和偶回文串,

c661280411470yb的博客 1967

Manacher算法,别称马拉车

Manacher算法,别称马拉车题目:怎么找出一个字符串中回文的最长大小代码算法解读算法其他 题目:怎么找出一个字符串中回文的最长大小 ABAKK 最长回文为ABA,长度为3;abaaab最长回文为baaab,长度为5 代码 int len = str.length(); char* char_list = new char[len*2 + 1]; int * num_list = new int[len*2+1]; char_list[0] = '$'; int index = 0; for(int i=

火烧尾的专栏 300

Manacher(马拉车)算法总结

Manacher算法 在介绍算法之前,首先介绍一下什么是回文串,所谓回文串,简单来说就是正着读和反着读都是一样的字符串,比如abba,noon等等,一个字符串的最长回文子串即为这个字符串的子串中,是回文串的最长的那个。 计算字符串的最长回文字串最简单的算法就是枚举该字符串的每一个子串,并且判断这个子串是否为回文串,这个算法的时间复杂度为O(n^3)的,显然无法令人满意,稍微优化的一个算...

何世全的博客 4034

最长回文字符串——马拉车(Manacher)算法

最长回文字符串——马拉车(Manacher)算法 说来惭愧,都快要毕业了才写第一篇博客。。。 回文串 回文串呢,就是在一个字符串中,左半部分和右半部分是镜像对称的字符串,比如abcba,就是一个已c为中心点的回文串。当然,abccba也是一个回文串,所以回文串可以是奇数亦可以是偶数。 问题 怎么在一个字符串中求出最长的回文串 正常思路 我们的都会想到从左往右以每个字符为中心往这个字符的两边去拓展搜索字符串的长度,就像是abcbad=>abcbad=>abcbad。但是前面也说到了回文串也可以是

qq_34025034的博客 655

Manacher算法(马拉车)

Manacher(马拉车)算法

Mibbp的博客 541

Manacher (马拉车)算法

Manacher于1975年发现了一种线性时间算法,可以在列出给定字符串中从任意位置开 始的所有回文子串。同样的算法也可以在任意位置查找全部极大回文子串,并且时间复杂 度是线性的。那他是怎样实现的呢,别着急继续往下看。 我们先看一下回文串,回文串有两种形式,一种是奇数的比如"aba",一种是偶数的比 如"abba"。这里使用Manacher算法的时候,会在每个字符之间都会插入一个特殊字 符,并且两边也会插入,这个特殊字符要保证不能是原字符串中的字符,这样无论原来字 符串长度是奇数还是偶数,添加之后长度都

weixin_52914088的博客 767

Manacher 马拉车 算法

文章目录ManacherFirstSecondProblem 1Problem 2ThirdCode寻找原字符串中起始字符的位置 Manacher 马拉车算法用于寻找最长回文串。 其思路如下: First 首先,对于一个字符串,其子串的长度一定是奇数或者偶数。判断回文串过程中也是如此,这就增加了判断的难度。对此,马拉车算法采用如下方法将要找的子串全部变为奇数长度:在每个字符前添加同一个字符#。 也...

Zoybzo想AK 203

Manacher(马拉车)算法

由解最长回文子序列 了解Manacher(马拉车)算法

m0_63901241的博客 1306
上一篇: 【小记】获取客户端用户真实ip方法整理 from jekyll
下一篇: 【算法】下一个排列
皮皮蟹01
博客等级 码龄10年 29粉丝 76原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值