寻找字符串中的最长回文序列和所有回文序列(正向和反向一样的序列,如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. Jquery easyui-combobox 的一个BUG

    通过easyui-combobox的loadData方法,easyui-combobox可以实现一个带字符搜索的下拉框,如下图: 但是这个下拉框中的字符串如果包含一些特殊字符的时候,就会出现BUG,通 ...

  2. [双连通分量] POJ 3177 Redundant Paths

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13712   Accepted: 5821 ...

  3. BCG界面库下的Windows8 UI界面样式www.webui8.com

    BCG界面库下的Windows8 UI界面样式(Metro风格)控件主要有以下一些功能: 规则的大块磁贴 支持完整键盘导航 Tile组 标题(Caption) 标题按钮(Caption buttons ...

  4. 在Mac环境下跑汇编

    今天汇编作业做到第七章,就想在Mac下跑自己的asm程序,看到了一个很好的教程: http://www.raywenderlich.com/37181/ios-assembly-tutorial 虽然 ...

  5. linux上安装php+gd扩展

    515 cd zlib-1.2.3 516 ./configure --prefix=/usr/local/zlib2 517 make && make install 518 cd ...

  6. IP地址的分类——a,b,c 类是如何划分的

    现在的IP网络使用32位地址,以点分十进制表示,如172.16.0.0.地址格式为:IP地址=网络地址+主机地址 或 IP地址=主机地址+子网地址+主机地址. IP地址类型 最初设计互联网络时,为了便 ...

  7. 动手实现自己的 STL 容器 《1》---- vector

    本文参考了侯捷的 <STL 源码分析>一书,出于兴趣,自行实现了简单的 vector 容器. 之后会陆续上传 list, deque 等容器的代码,若有错误,欢迎留言指出. vector ...

  8. QT_BEGIN_NAMESPACE QT_END_NAMESPACE

    QT_BEGIN_NAMESPACEQT_END_NAMESPACE 在源代码中是这样定义的: 1 2 # define QT_BEGIN_NAMESPACE namespace QT_NAMESPA ...

  9. HDU1005(矩阵快速幂)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1005 #include<cstdio> using namespace std; int ...

  10. IOS网络开发(三)

    1 飞机航班查询软件 1.1 问题 NSURLConnection是IOS提供的用于处理Http协议的网络请求的类,可以实现同步请求也可以实现异步请求,本案例使用NSURLConnection类实现一 ...