转自 http://blog.sina.com.cn/s/blog_3fe961ae0101iwc2.html

寻找字符串中的回文,有特定的算法来解决,也是本文的主题:Manacher算法,其时间复杂度为O(n)。

首先在每两个相邻字符中间插入一个分隔符,当然这个分隔符要在原串中没有出现过。一般可以用‘#’分隔。这样就非常巧妙的将奇数长度回文串与偶数长度回文串统一起来考虑了。

然后,我们需要一个辅助数组rad[],用rad[i]表示第i个字符的回文半径,rad[i]的最小值为1,即只有一个字符的情况,现在问题转变成如何求出rad数组。

假设现在求出了rad[1, ..., i],现在要求后面的rad值,再假设现在有个指针k,从1循环到rad[i],试图通过某些手段来求出[i + 1, i + rad[i] - 1]的rad值,其分析如下:

如图1所示,黑色的部分是一个回文子串,两段红色的区间对称相等。因为之前已经求出了rad[i - k],所以可以避免一些重复的查找和判断,有3种情况:

图1

①  rad[i] - k < rad[i - k]

如图1,rad[i - k]的范围为青色。因为黑色的部分是回文的,且青色的部分超过了黑色的部分,所以rad[i + k]肯定至少为rad[i]-k,即橙色的部分。那橙色以外的部分就不是了吗?这是肯定的,因为如果橙色以外的部分也是回文的,那么根据青色和红色部分的关系,可以证明黑色部分再往外延伸一点也是一个回文子串,这肯定是不可能的,因此rad[i + k] = rad[i] - k。

②  rad[i] - k > rad[i - k]

如图2,rad[i-k]的范围为青色,因为黑色的部分是回文的,且青色的部分在黑色的部分里面,根据定义,很容易得出:rad[i + k] = rad[i - k]。根据上面两种情况,可以得出结论:当rad[i] - k != rad[i - k]的时候,rad[i + k] = min(rad[i] - k, rad[i - k])。

图2

③  rad[i] - k = rad[i - k]

如图,通过和第一种情况对比之后会发现,因为青色的部分没有超出黑色的部分,所以即使橙色的部分全等,也无法像第一种情况一样引出矛盾,因此橙色的部分是有可能全等的。但是,根据已知的信息,我们不知道橙色的部分是多长,因此就需要再去尝试和判断了。

Manacher 计算最长回文串的更多相关文章

  1. Manacher(最长回文串)

    http://acm.hdu.edu.cn/showproblem.php?pid=3068 最长回文 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符 ...

  2. Manacher算法,最长回文串

    给你10000长度字符串,然你求最长回文字串,输出长度,暴力算法肯定超时 #include <iostream> #include <string> #include < ...

  3. manacher 算法(最长回文串)

    manacher算法: 定义数组p[i]表示以i为中心的(包含i这个字符)回文串半径长 将字符串s从前扫到后for(int i=0;i<strlen(s);++i)来计算p[i],则最大的p[i ...

  4. Manacher算法 - 求最长回文串的利器

    求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...

  5. 字符串的最长回文串:Manacher’s Algorithm

    题目链接:Longest Palindromic Substring 1. 问题描述 Given a string S, find the longest palindromic substring ...

  6. Manacher's Algorithm 马拉车算法(求最长回文串)

    作用:求一个字符串中的最长子串,同时还可以求所有子串的长度. 题目链接: https://vjudge.net/contest/254692#problem/B 最长回文串长度的代码: int Man ...

  7. Hdu 3294 Girls' research (manacher 最长回文串)

    题目链接: Hdu 3294  Girls' research 题目描述: 给出一串字符串代表暗码,暗码字符是通过明码循环移位得到的,比如给定b,就有b == a,c == b,d == c,.... ...

  8. Manacher模板(O(n)内求最长回文串长度)

    转自:https://segmentfault.com/a/1190000008484167 /* 由于回文分为偶回文(比如 bccb)和奇回文(比如 bcacb),而在处理奇偶问题上会比较繁琐,所以 ...

  9. hdu 3068 最长回文 (Manacher算法求最长回文串)

    参考博客:Manacher算法--O(n)回文子串算法 - xuanflyer - 博客频道 - CSDN.NET 从队友那里听来的一个算法,O(N)求得每个中心延伸的回文长度.这个算法好像比较偏门, ...

随机推荐

  1. PHP服务器访问优化

    常规的优化措施: 磁盘写入,网络安全,证书加密,CPU,内存,DNS解析,数据库优化,页面gzip压缩 PHP gzip压缩打开: 打开php目录下的php.ini文件,找到zlib.output_c ...

  2. Microsoft Office Enterprise 2007 在安装过程中出错的解决方法

    今天笔者在使用PowerPoint 2007打开一个ppt的内嵌的excel表格时报如下错误: 无法找到 服务器应用程序.源文件.和项目,或返回的未知错误.请重新安装服务程序 然后就先把ppt文件发给 ...

  3. 解决 java.lang.IllegalThreadStateException: Thread already started. 错误

    extends:http://blog.csdn.net/liuhanhan512/article/details/7575386 android开发中,对线程的操作比较悲催,start一个线程后,必 ...

  4. h5页面弹窗滚动穿透的思考

    可能我们经常做这样的弹窗对吧,兴许我们绝对很简单,两下搞定: 弹窗的页面结构代码: <!-- 弹窗模块 引用时移除static_tip类--> <div class="ma ...

  5. Ubuntu 16.04系统下安装Discuz出现“HTTP ERROR 500”目前无法处理此请求

    问题:当我们在Ubuntu 16.04系统下安装Disucz X3时,修改好文件的权限,浏览器输入地址安装时出现如下图所示问题: 问题查询: 在终端输入: tail -f /var/log/apach ...

  6. SDWebImage第三方库使用注意的一些问题

    1.利用"UIImageView+WebCache.h"加载图片数据 例如: UIImage *placeHolderImg = [UIImage imageNamed:@&quo ...

  7. 冒泡排序算法的 python 实现与 C 的比较

    昨天用c写了简单的冒泡排序算法之后,正好最近在学 python,也想试试用python实现一下. 总体感觉,对于这种简答的小程序,python 确实充分体现了他简洁,易懂的特点.写起来特别流畅,舒服. ...

  8. CSS垂直导航栏

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. ArcGIS API for javascript开发笔记(四)——GP服务调用之GP模型的规范化制作详解

    感谢一路走来默默陪伴和支持的你~~~ -------------------欢迎来访,拒绝转载------------------- 在之前的利用Python分析GP服务运行结果的输出路径 & ...

  10. PHP漏洞-Session劫持

    http://os.51cto.com/art/201204/328888.htm