寻找字符串中的最长回文序列和所有回文序列(正向和反向一样的序列,如aba,abba等)算是挺早以前提出的算法问题了,最近再刷Leetcode算法题的时候遇到了一个(题目),所以就顺便写下。

如果用正反向遍历的方法的话时间复杂度将会是O(N^2),而利用Manacher算法将会是O(N),在处理长序列的时候能显著提高速度。

算法原理

  1. 回文序列的左右是对称的,也就是说在找到一个回文序列的时候,回文序列的右半部份将会是左半部分的镜像,在符合一定条件的时候可以直接判断以当前字符为中心的回文序列的长度

    以下图为例(途中的#是在编程过程中为了将原来的偶数长度的回文序列转化为奇数长度,简化代码)

  2. 从左边开始分析,上一次寻找倒的的回文序列的中心记为C,当前位置记为R,与之通过C镜像相对的位置记为L。如果R加上通过L获知的当前位置可能的回文序列半径之后的位置还处于C的回文序列范围内,那么R位置的回文序列长度就与L处相等,最长回文序列的中心仍为C。记录当前位置为中心的回文序列半径(P)。
  3. 如果上述条件不成立,那么R将成为新的回文序列中心,这时以R为中心向两边同时延伸,直到遇到不同字符位置,获取此时以R为中心的回文序列长度。记录(P)
  4. 重复上述过程直至最后一个字符
  5. 获取最长半径所对应的字符坐标,即可得到最长的回文序列

    PS:如果只需要直到最长序列,那么更新C只在当前最标下的回文序列半径之前最长的还要长的时候才进行,这样操作的话能直接获得最长回文序列中心坐标。

实现代码

class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
center = 0
# insert dollar signs between each character
s = '$' + '$'.join(list(s)) + '$'
radius_lengths = [1] * len(s)
for index, _ in enumerate(s):
if center + radius_lengths[center] > index+radius_lengths[index]:
radius_lengths[index] = radius_lengths[2*center-index]
while index-radius_lengths[index] >= 0 and index+radius_lengths[index] < len(s) and s[index-radius_lengths[index]] == s[index+radius_lengths[index]]:
radius_lengths[index] += 1
if radius_lengths[center] < radius_lengths[index]:
center = index
pali = s[center-radius_lengths[center]+2:center+radius_lengths[center]:2]
return pali
obj = Solution()
s = "abb"
print obj.longestPalindrome(s)

当前将会输出bb。

参考资料

  1. https://en.wikipedia.org/wiki/Longest_palindromic_substring
  2. http://articles.leetcode.com/longest-palindromic-substring-part-ii/
  3. http://www.geeksforgeeks.org/manachers-algorithm-linear-time-longest-palindromic-substring-part-1/

利用Manacher算法寻找字符串中的最长回文序列(palindrome)的更多相关文章

  1. 实现一个算法,寻找字符串中出现次数最少的、并且首次出现位置最前的字符 如"cbaacfdeaebb",符合要求的是"f",因为他只出现了一次(次数最少)。并且比其他只出现一次的字符(如"d")首次出现的位置最靠前。

    实现一个算法,寻找字符串中出现次数最少的.并且首次出现位置最前的字符如"cbaacfdeaebb",符合要求的是"f",因为他只出现了一次(次数最少).并且比其 ...

  2. [hdu3068 最长回文]Manacher算法,O(N)求最长回文子串

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意:求一个字符串的最长回文子串 思路: 枚举子串的两个端点,根据回文串的定义来判断其是否是回文 ...

  3. ZT 查找字符串中连续最长的数字串

    查找字符串中连续最长的数字串 有俩方法,1)比较好理解一些.2)晦涩 1) /* 功能:在字符串中找出连续最长的数字串,并把这个串的长度返回, 并把这个最长数字串付给其中一个函数参数outputstr ...

  4. POJ-3294-Life Forms(后缀数组-不小于 k 个字符串中的最长子串)

    题意: 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. 分析: 将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组. 然后二分答案,将后缀分成若干组,判断 ...

  5. Life Forms POJ - 3294(不小于k个字符串中的最长子串)

    题意: 求不小于字符串一半长度个字符串中的最长字串 解析: 论文题例11 将n个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开, 求后缀数组, 然后二分答案变为判定性问题, 然后判断每组的 ...

  6. poj 3294 后缀数组 多字符串中不小于 k 个字符串中的最长子串

    Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 16223   Accepted: 4763 Descr ...

  7. 第5题 查找字符串中的最长回文字符串---Manacher算法

    转载:https://www.felix021.com/blog/read.php?2040 首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一 ...

  8. Manacher算法讲解——字符串最长回文子串

    引 入 引入 引入 Manachar算法主要是处理字符串中关于回文串的问题的,这没什么好说的. M a n a c h e r 算 法 Manacher算法 Manacher算法 朴素 求一个字符串中 ...

  9. 利用split方法计算字符串中出现字母最多的次数

    最近练习一些简单的算法题,知道自己很不聪明,但却没想到用了这么久,划算不划算是个需要考虑的问题, 其中有个算法是:统计一个字符串出现最多的字母,网上很多自己的见解,但是才疏学浅,有些地方看的有点困难, ...

随机推荐

  1. Octopus系列之一些问题的汇总

    1._WidgetCart.html中的数量更新函数和删除函数,转移到MyShoppingCart.html中出错 如果你使用的是jQuery的方式banding函数 比如change 和click, ...

  2. C#微信公众号开发-高级接口-之模板消息开发,附源码

    个人觉得模板消息功能的增加对公众号的作用非常大,可以说是真正意义上的实现了所谓的轻app,商家可以通过模板消息给用户发送重要的信息,交易.预约.消费.邮件.物流等信息.之前我做过的系统通过邮件发送订单 ...

  3. sonar-gerrit-plugin-2.2.0 安装

    这是一个很新的插件国内使用的用户还是很少的,公司有需要才花了一段时间去研究. 作用:在 code review的时候可以将sonar的检测结果直接集成返回.帮助po对code 进行review. 请严 ...

  4. css伪元素选择器(伪对象选择器)checked + 伪元素练习

    伪对象也叫伪元素,在过去,伪类和伪元素都被书写成前面只加一个冒号,实际上应该是: :weilei ::伪元素 而现在我们为了兼容旧的书写方式,用一个冒号引导伪类也是能被解析的. 伪类一般反应无法在CS ...

  5. 最小割 总结&&做题记录

    模型要点: 1.一般适用于二取一问题或者01规划. 2.利用最小割=最大流,转化为最大流求之. 建议阅读胡伯涛的论文 <<最小割模型在信息学竞赛的应用>>,有精彩有序的证明和各 ...

  6. cloud theory is a failure? 分类: Cloud Computing 2013-12-26 06:52 269人阅读 评论(0) 收藏

    since LTE came out, with thin client cloud computing  and broadband communication clouding 不攻自破了.but ...

  7. poj3660 floyd

    //Accepted 176 KB 16 ms //一头牛,如果rank是能确定的,那么能打败他的牛的个数和被他打败的牛的个数的总和为n-1 #include <cstdio> #incl ...

  8. 动手实现自己的 STL 容器《2》---- list

    1. 序: 本文参考了侯捷的 <STL 源码分析>一书,出于兴趣,自行实现了简单的 list 容器. 学习了 STL 的 list 容器的源代码,确实能够提高写链表代码的能力.其中的 so ...

  9. Linux Centos7下安装Python

    1.查看是否已经安装Python Centos7默认安装了python2.7.5 因为一些命令要用它比如yum 它使用的是python2.7.5. 使用python -V命令查看一下是否安装Pytho ...

  10. MVC中的自定义控件——分页

    上一篇是个简单例子,这篇借分页写个升级版的例子. 不想拼html代码,因为不好修改,那写一个PartialView. @model System.Web.Mvc.PagerModel @if (Mod ...