寻找字符串中的最长回文序列和所有回文序列(正向和反向一样的序列,如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. 介绍开源的.net通信框架NetworkComms框架之八 UDP通信

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  2. Scala HelloWorld

    1) 使用MVN创建项目 mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtif ...

  3. redhat6.4上用apache建立os repos

    1.挂载OS介质文件 [root@server- Packages]# mkdir -p /media/dvd [root@server- Packages]# -20130130.0-Server- ...

  4. Windows Server 2003 Sp2 下无法安装SQL Server 2008 Management Studio Express问题

    Windows Server 2003 Sp2 下无法安装SQL Server 2008 Management Studio Express问题钉子 发表于 2010-5-22 1:42:51问题描述 ...

  5. 运用Fluxion高效破解WiFi密码

    Fluxion是一个无线破解工具,这个工具有点像是Linset的翻版.但是与Linset比较起来,它有着更多有趣的功能.目前这个工具在Kali Linux上可以完美运行. 工作原理 1.扫描能够接收到 ...

  6. mysql触发器使用

    触发器 简要 1.触发器基本概念 2.触发器语法及实战例子 3.before和after区别 一.触发器基本概念 1.一触即发 2.作用: 监视某种情况并触发某种操作 3.观察场景 一个电子商城: 商 ...

  7. HttpClient(4.3.3)实例讲解

    HttpClient的作用强大,真的是十分强大. 本实例是基于v4.3.3写的,,作用是模拟登陆后进行上下班打卡,,,使用htmlparser进行解析返回的html文件 关于HttpClient的一些 ...

  8. C语言之const和define

    const修饰的是只读变量,不是常量,其值在编译时不能被使用,因为编译器在编译时不知道其存储的内容.编译器通常不为普通const只读变量分配存储空间,而使将他们保存在符号表中,这使得他成为一个编译期间 ...

  9. [GodLove]Wine93 Tarining Round #3

    比赛链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=44857#overview 题目来源: ZOJ Monthly, July 2 ...

  10. 2016年12-09php函数

    php函数 函数名,参数列表,函数体 php时弱类型语言返回类型可以没有function 函数名(){} 1.简单函数四要素:返回类型,函数名,参数列表,函数体 function Show(){ ec ...