Manacher算法求最长回文

求最长回文子串的Manacher算法 最长回文子串以前一直是用后缀数组求的,今天看到一篇好文章写求O(n)求最长回文串的做法,所以呢就做个笔记 http://zhuhongcheng.wordpress.com/2009/08/02/a-simple-linear-time-algorithm-for-finding-longest-palindrome-sub-string/   英文的 http://acm.uestc.e 阅读详情

O(n)回文子串算法
    这里,我介绍一下O(n)回文串处理的一种方法。Manacher算法.
原文地址:
点击打开链接
    其实原文说得是比较清楚的,只是英文的,我这里写一份中文的吧。
    首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长。这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文有多长,
    这个算法有一个很巧妙的地方,它把奇数的回文串和偶数的回文串统一起来考虑了。这一点一直是在做回文串问题中时比较烦的地方。这个算法还有一个很好的地方就是充分利用了字符匹配的特殊性,避免了大量不必要的重复匹配。
    算法大致过程是这样。先在每两个相邻字符中间插入一个分隔符,当然这个分隔符要在原串中没有出现过。一般可以用‘#’分隔。这样就非常巧妙的将奇数长度回文串与偶数长度回文串统一起来考虑了(见下面的一个例子,回文串长度全为奇数了),然后用一个辅助数组P记录以每个字符为中心的最长回文串的信息。P[id]记录的是以字符str[id]为中心的最长回文串,当以str[id]为第一个字符,这个最长回文串向右延伸了P[id]个字符。
    原串:    w aa bwsw f d 
    新串:   # w # a # a # b # w # s # w # f # d #
辅助数组P:  1 2 1 2 3 2 1 2 1 2 1 4 1 2 1 2 1 2 1
    这里有一个很好的性质,P[id]-1就是该回文子串在原串中的长度(包括‘#’)。如果这里不是特别清楚,可以自己拿出纸来画一画,自己体会体会。当然这里可能每个人写法不尽相同,不过我想大致思路应该是一样的吧。
    好,我们继续。现在的关键问题就在于怎么在O(n)时间复杂度内求出P数组了。只要把这个P数组求出来,最长回文子串就可以直接扫一遍得出来了。
    由于这个算法是线性从前往后扫的。那么当我们准备求P[i]的时候,i以前的P[j]我们是已经得到了的。我们用mx记在i之前的回文串中,延伸至最右端的位置。同时用id这个变量记下取得这个最优mx时的id值。(注:为了防止字符比较的时候越界,我在这个加了‘#’的字符串之前还加了另一个特殊字符‘$’,故我的新串下标是从1开始的)

好,到这里,我们可以先贴一份代码了。

void pk()
{
    int i;
    int mx = 0;
    int id;
    for(i=1; i<n; i++)
    {
        if( mx > i )
            p[i] = MIN( p[2*id-i], mx-i );        
        else
            p[i] = 1;
        for(; str[i+p[i]] == str[i-p[i]]; p[i]++)
            ;
        if( p[i] + i > mx )
        {
            mx = p[i] + i;
            id = i;
        }
    }
}

代码是不是很短啊,而且相当好写。很方便吧,还记得我上面说的这个算法避免了很多不必要的重复匹配吧。这是什么意思呢,其实这就是一句代码。

if( mx > i )
    p[i] = MIN( p[2*id-i], mx-i );

就是当前面比较的最远长度mx>i的时候,P[i]有一个最小值。这个算法的核心思想就在这里,为什么P数组满足这样一个性质呢?
   (下面的部分为图片形式)

看完这个算法,你有可能会觉得这种算法在哪会用到呢?其实回文串后缀数组也可以做。只是复杂度是O(n log n)的,而且一般情况下也不会刻意去卡一个log n的算法。可正好hdu就有这么一题,你用后缀数组写怎么都得T(当然应该是我写得太烂了)。不信的话大家也可以去试试这题。


点击打开链接


另外,顺便附一份AC代码。


点击打开链接

Manacher算法 求最长回文子串 ACM模板 Manacher 求最长回文子串 ACM模板 C++ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 100000 + 10; char Ma[MAXN <&... 阅读详情

相关推荐

Manacher算法求最长回文串

最长回文Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6442    Accepted Submission(s): 2227Problem Description给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长

优快云 2352

Manacher算法--O(n)回文子串算法

O(n)回文子串算法 注:转载的这篇文章,我发现下面那个源代码有点bug。。。在下一篇博客中改正了。。       这里,我介绍一下O(n)回文串处理的一种方法。Manacher算法. 原文地址: http://zhuhongcheng.wordpress.com/20

xuanflyer 7万+

endnote让参考文献整整齐齐

这篇文章主要是针对利用 endnote 插入参考文献时,参考文献第一行和后面的行对不齐的问题 下面是示意图 可以看到我们的参考文献对的整整齐齐的,比较好看。 下面介绍具体步骤 1、打开endnote。编辑我们使用的参考文献样式。我这儿是叫 ZZ_MODIFIED_GEEBINF 复制 2、找到布局,每个参考开头,将光标放在在参考开头后面,点插入字段,制表符 3、右下角悬挂式输出哪儿选择全部段...

雾隐雾现的至渝博客 5万+

Mannacher 算法

Mannacher 算法 马拉车算法(中文翻译,有点搞笑)主要是用来求解字符串的最大回文字串。回文串是一个很常出现的东西,求解字符串的回文串也是很经典的题目,马拉车算法是一个可以在O(n)O(n)O(n)复杂度内求解字符串的最大回文串的算法。 基本介绍 在求解前我们要先对该字符串做一些预处理,其过程为: 在字符串的最前面加上"@#", 当然这两个符号都不能出现字符串当中,之后在字符串每个字符后面加...

weixin_39393640的博客 595

基于Kubernetes的ML平台架构设计

本文在Kubernetes开源组件的基础上,对ML平台各部分组件的作用进行了介绍,并且进行了组件选型,初步设计了ML平台的技术架构。

2401_83124266的博客 2052

从维纳滤波到Richardson-Lucy:图像去模糊算法的原理与实践

本文深入解析了图像去模糊的核心原理,重点对比了维纳滤波与Richardson-Lucy两种经典去卷积算法。维纳滤波在频域进行快速权衡,适用于高斯噪声场景;而Richardson-Lucy算法基于泊松噪声模型迭代优化,更适用于天文、显微等科学成像。文章通过Python代码实践,详细阐述了PSF(点扩散函数)的关键作用及算法选型指南。

weixin_29285605的博客 385

马拉车算法,mannacher查找最长回文子串

作用: 在线性时间内找到一个字符串的最大回文子串 原理: 奇偶变换:为处理字符串方便,现将给定的任意字符串进行处理,使所有可能的奇数/偶数长度的回文子串都转换成了奇数长度。 具体就是在每个字符的两边都插入一个特殊的符号。比如hhjj变成 #h#h#j#j#, aba变成 #a#b#a#; 为防止数组越界,可以在字符串的开始加入另一个特殊字符,比如“?#a#b#a#?” 。 定...

a6334167的博客 218

用AI免费制作30分钟电影:完整工作流与实操解析

AI视频生成技术正大幅降低影视创作门槛,但真正制作一部完整电影并非一键生成,而是涉及剧本、分镜、画面、配音、剪辑的复杂流水线。理解其基本原理,是将文本转化为连续视觉叙事的关键。对于创作者而言,掌握角色一致性控制、素材批量管理、免费额度合理分配等技术价值,能有效避免生成结果崩坏与资源浪费。该能力可广泛应用于短视频创作、独立电影预演、教学演示等场景。本文以30分钟AI电影制作为例,拆解从工具选择到成片输出的全流程,重点分析免费方案下的时间与积分成本,以及最容易翻车的环节,并给出基于实践验证的排查与优化策略。

weixin_29056865的博客 318

Manacher算法

Manacher算法又叫马拉车算法,是用来解决最长回文子串长度的问题的。可以通过O(N)的时间复杂度求出最长回文子串,它也会有很多的拓展运用。Mannacher算法也和KMP算法一样有一个数组来记录信息,这个数组是来记录最长回文半径的数组。我们先来看看回文半径的概念对于原字符串中的每一个字符,以这个字符为中心的最长回文串长度的一半向上取整就是其回文半径。然后还有两个变量,一个为C,一个为R。R:最长回文的区间右边界的最大值。C:右边界最大值所对应的中心点,也就是R所对应的圆心。下面举两个例子。

m0_74234328的博客 1171

信贷审批中的那些坑:从零开始搭建风控策略体系的5个关键步骤

本文深入探讨了信贷审批中的风控策略体系搭建,从数据陷阱识别、规则冲突诊断到反欺诈攻防,提供了5个关键步骤的实战指南。重点解析了如何通过特征工程、决策树优化和模型可解释性技术,构建动态平衡的风控体系,有效降低逾期风险并提升审批效率。

weixin_29253711的博客 411

电池管理系统(BMS)软件:CATL BMS二次开发_(1).CATL BMS软件概述

CATL BMS软件的保护机制是确保电池组安全和可靠运行的关键部分。通过高精度的传感器和智能算法,BMS可以实时监测电池组的状态,及时采取保护措施。二次开发中,可以根据特定的应用需求,增加新的传感器、优化算法、扩展通信接口等,进一步提高系统的性能和可靠性。维护和扩展则是确保系统长期稳定运行的重要手段。希望以上内容对您理解CATL BMS软件的保护机制有所帮助。如果您有任何进一步的问题或需要更详细的解释,欢迎随时提问。

zhubeibei168的博客 1457

刷题DAY13

手撕mannacher算法总之是找最长回文字符串最暴力的解法是什么呢你就枚举每一个字符 往左右扩 看它每步一不一样 但是这个恶心在哪呢 1221这样的回文字符串 你找不到它的对称轴 它是虚轴那我们怎么优化呢 1#2#2#1 哎 这样就能把虚轴给枚举出来了哎 你可能会问 啊 那我字符串中本来就有#咋办 假如说 #22# 我转化成##2#2## 影响吗?他该是回文还是回文啊 不是回文咋填都不是回文 填一都行但是这样实在是太暴力了 我们选择进行优化 也就引出了mannacher算法。

chara9885的博客 132

RK3399外设驱动之MIPI

RK3399外设驱动之MIPI 文章目录RK3399外设驱动之MIPIMIPI命令解析入口代码mipi显示配置实例rk3399mipi驱动rk mipi驱动注册过程rk32_mipi_dsi.c解析 内核版本 Linux4.4 平台 rk3399 作者 nineyole MIPI命令解析入口代码 MIPI的入口代码如下:kernel\drivers\video\rockchip\screen\lcd_mipi.c static int __init rk_mipi_screen_in

学无止境 2227

manacher算法求最长回文串

求最长回文串可以使用manacher算法来达到O(n)时间内得出结果,之所以降到O(n)是因为减少了很多重复匹配。思路如下:1.把所有字符串都变成奇数个字母的串,方法很简单,就是在所有字母前后加一个特殊字符,比如常用’#’,这样长度为n的串就变成了长度为2*n+1的串,即奇数串,然后在为了在代码中减少边界的判断,分别在首位加另外的特殊字符,一般在首部加个’$’,而尾部自然用字符串的结尾标志’\0’即

凌风 1899

标准测试测试数据STDF学习笔记

本文介绍了STDF(Standard Test Data Format)文件的结构与解析方法。首先详细说明了STDF记录的组成,包括记录头类型(REC_TYP和REC_SUB)、数据类型定义、时间日期格式以及无效数据标识。重点分析了25种主要记录类型的功能、数据内容和出现位置,如FAR、MIR、MRR等关键记录。然后介绍了基于pystdf开源工具的解析方法,包括自带脚本的使用和自编程解析流程,通过事件驱动机制处理数据流。特别指出测试数据是按照PIR→PTR/MPR/FTR→PRR的循环模式组织。文章为ATE

歌颂苦难的行为是无耻的; 1513

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

求最长回文串(Manacher算法)

普通求回文串方法分析: 我们在平常做题的时候呢,有时候会遇到需要求最长回文串的要求,回文串就是从左读和从右读完全一样的字符串,如 aaaa , ababa, baab, 这样类型的字符串,我们初始的比较省时省力的方法呢,就是从中间往两边扩,但是因为回文串有奇偶之分,所以判断回文串的时候,需要用两种方法来判断,一种判断奇数个的时候的回文串,一种判断偶数个的时候的回文串,所以,我用两个函数来解决,分...

Ripcord丶的博客 406

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

manacher算法 求最长回文串

本题链接:用户登录 根据题目意思,求出最长回文串,我们可以用模板 manacher 算法 求最长回文串。 manacher算法 求最长回文串 核心有两个步骤。 一、将字符串转化为 奇数 长度的字符串,方便我们求回文串。 二、利用回文串对称性的特点,推导最长回文串长度。 根据我们的核心开始一步一步来。 我们把每个字符作为回文串的中心去处理。 我们只要在每个字符中间加入一

Angindem博客 921

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Manacher算法求最长回文子串

时间复杂度O(n) 算法的主要思想是从左到右处理字符串,求每个位置为中心的两端对称的最大半径。 void Manacher(char s[],int n,int radius[]) { int i,j; for(i=1;i<n;i++) radius[i]=1; for(i=2;i<n;i=j) { whil

ashuai81的专栏 2394

Manacher算法——求最长回文子串

Manacher算法是用来求解一个给定字符串的最长回文子串,回文就是将字符串翻转后,与原来一样。这个算法通过添加字符,巧妙的将回文长度为偶数的情况转化成奇数,简化了问题的步骤,并且利用回文的性质,将去除了冗余的比较,从而将复查度降到O(len),能够求出以每个字符为中心的最长回文,从而求出最长的回文子串。 现在,简述一下算法的过程: 在相邻的两个字符之间(包括首尾)添加特殊字符(也就是

志当存高远 2293

Manacher 算法 求最长回文子串

刷LeetCode的时候有一题,提到了一个算法Manacher,可以在时间复杂度O(n)的情况下求出最长的回文子串,既然是一个没听过看过的算法,就去查了下并自己实现了下效果,在这纪录一下。 题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/ 回文子串:通俗的讲就是正序倒序都一样的字符串,例如aba,abba,...

王王王渣渣的博客 417

Manacher算法-求最长回文子串

我们先来讲一下Manacher是用来干什么的,它是求回文串的,什么是回文,解释一下,一个字符串,如果它正过来念和反过来念是一样的,那么它就是回文,比如说 12321,这是一个奇数长度的回文,当然偶数也一样,例如 123321。总而言之,回文就是存在一个轴,这个轴可能真的压在某一个字符上,也可能压在一个虚的位置,左右两边是逆序的关系,它就是所谓的回文。那我们求一个什么问题, 我们求一个字符串中的最长回文子串,注意,子串,一定是连续的。

KudouShinichi3的博客 1083

求最长回文子串——Manacher算法详解

回文子串问题 回文子串问题通常会给出一个字符串,然后找出这个字符串中最长的回文子串。 回文串即为正读和反读一致的字符串,比如”aa&amp;amp;amp;quot;,“abba”,&amp;amp;amp;quot;abcba&amp;amp;amp;quot;等。判别一个字符串是否为回文串很容易想到的方法是: 设立两个游标,分别在串的最左和最右,让这两个游标向对方逼近的同时比较这两个游标的值 但是这里我们要讨论的是回文子串,所以上述方法暴露出一个严重的缺陷:难以确定右游标(因

Ekmr的博客 316

Manacher算法/O(n)时间复杂度求字符串中最长回文子字串算法

Manacher算法/O(n)时间复杂度求字符串中最长回文子字串算法 刷leetcode的5.Longest Palindromic Substring时被虐的要死要活的……找了一下才发现历史上已有存在的最优算法,manacher(马拉车)算法。 但网上大多数博客都晦涩难懂,在此用简单的语言解释、记录一下。 java代码实现在文末。 规则: 1、最长回文子串的长度是半径减1...

wu2007369的博客 350

使用Manacher算法求最长回文子串

• 给出一个字符串,要求计算出这一字符串的最长回文子串的长度。 如果遍历每一个字符,并以该字符为中心向两边查找,则其时间 复杂度为O(n2)。 • Manacher算法,又被戏称为“马拉车”算法,可以在时间复杂度 为O(n)的情况下求解一个字符串的最长回文子串的长度。 • 由于回文分为偶回文(例如"bccb")和奇回文(例如"bcacb"), 而在处理奇偶问题上会比较繁琐,例如,对于偶回文"bccb",其 对称中心是在两个‘c’字符之间;对于奇回文"bcacb",对称中心就 是‘a’字符。对此,Manach

K_e_L_e的博客 180

manacher算法求最长回文串长度

manacher算法: 定义数组p[i]表示以i为中心的(包含i这个字符)回文串半径长 将字符串s从前扫到后for(int i=0;i 由于s是从前扫到后的,所以需要计算p[i]时一定已经计算好了p[1]....p[i-1] 假设现在扫描到了i+k这个位置,现在需要计算p[i+k] 定义maxlen是i+k位置前所有回文串中能延伸到的最右端的位置,即maxlen=p[i]+i;//p[i

1.3秒前 608
上一篇: 实验室纳新
下一篇: POJ1562
Daemoonn
博客等级 码龄11年 42粉丝 198原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值