利用Manacher算法寻找字符串中的最长回文序列(palindrome)
寻找字符串中的最长回文序列和所有回文序列(正向和反向一样的序列,如aba,abba等)算是挺早以前提出的算法问题了,最近再刷Leetcode算法题的时候遇到了一个(题目),所以就顺便写下。
如果用正反向遍历的方法的话时间复杂度将会是O(N^2),而利用Manacher算法将会是O(N),在处理长序列的时候能显著提高速度。
- 回文序列的左右是对称的,也就是说在找到一个回文序列的时候,回文序列的右半部份将会是左半部分的镜像,在符合一定条件的时候可以直接判断以当前字符为中心的回文序列的长度
以下图为例(途中的#是在编程过程中为了将原来的偶数长度的回文序列转化为奇数长度,简化代码)
- 从左边开始分析,上一次寻找倒的的回文序列的中心记为C,当前位置记为R,与之通过C镜像相对的位置记为L。如果R加上通过L获知的当前位置可能的回文序列半径之后的位置还处于C的回文序列范围内,那么R位置的回文序列长度就与L处相等,最长回文序列的中心仍为C。记录当前位置为中心的回文序列半径(P)。
- 如果上述条件不成立,那么R将成为新的回文序列中心,这时以R为中心向两边同时延伸,直到遇到不同字符位置,获取此时以R为中心的回文序列长度。记录(P)
- 重复上述过程直至最后一个字符
- 获取最长半径所对应的字符坐标,即可得到最长的回文序列
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。
参考资料
- https://en.wikipedia.org/wiki/Longest_palindromic_substring
- http://articles.leetcode.com/longest-palindromic-substring-part-ii/
- http://www.geeksforgeeks.org/manachers-algorithm-linear-time-longest-palindromic-substring-part-1/
利用Manacher算法寻找字符串中的最长回文序列(palindrome)的更多相关文章
- 实现一个算法,寻找字符串中出现次数最少的、并且首次出现位置最前的字符 如"cbaacfdeaebb",符合要求的是"f",因为他只出现了一次(次数最少)。并且比其他只出现一次的字符(如"d")首次出现的位置最靠前。
实现一个算法,寻找字符串中出现次数最少的.并且首次出现位置最前的字符如"cbaacfdeaebb",符合要求的是"f",因为他只出现了一次(次数最少).并且比其 ...
- [hdu3068 最长回文]Manacher算法,O(N)求最长回文子串
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意:求一个字符串的最长回文子串 思路: 枚举子串的两个端点,根据回文串的定义来判断其是否是回文 ...
- ZT 查找字符串中连续最长的数字串
查找字符串中连续最长的数字串 有俩方法,1)比较好理解一些.2)晦涩 1) /* 功能:在字符串中找出连续最长的数字串,并把这个串的长度返回, 并把这个最长数字串付给其中一个函数参数outputstr ...
- POJ-3294-Life Forms(后缀数组-不小于 k 个字符串中的最长子串)
题意: 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. 分析: 将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组. 然后二分答案,将后缀分成若干组,判断 ...
- Life Forms POJ - 3294(不小于k个字符串中的最长子串)
题意: 求不小于字符串一半长度个字符串中的最长字串 解析: 论文题例11 将n个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开, 求后缀数组, 然后二分答案变为判定性问题, 然后判断每组的 ...
- poj 3294 后缀数组 多字符串中不小于 k 个字符串中的最长子串
Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 16223 Accepted: 4763 Descr ...
- 第5题 查找字符串中的最长回文字符串---Manacher算法
转载:https://www.felix021.com/blog/read.php?2040 首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一 ...
- Manacher算法讲解——字符串最长回文子串
引 入 引入 引入 Manachar算法主要是处理字符串中关于回文串的问题的,这没什么好说的. M a n a c h e r 算 法 Manacher算法 Manacher算法 朴素 求一个字符串中 ...
- 利用split方法计算字符串中出现字母最多的次数
最近练习一些简单的算法题,知道自己很不聪明,但却没想到用了这么久,划算不划算是个需要考虑的问题, 其中有个算法是:统计一个字符串出现最多的字母,网上很多自己的见解,但是才疏学浅,有些地方看的有点困难, ...
随机推荐
- 使用scp将文件/目录拷贝到另一台Linux主机上
如何将一台Linux主机上的文件或目录拷贝到另一台Linux主机上,scp命令可以实现该需求 前提条件:两台Linux主机处于同一网段,可以互相ping通 操作如下: 文件拷贝 ①将本地文件拷贝到远端 ...
- nodejs gulp less编辑
nodejs 下载地址:http://pan.baidu.com/s/1bnz2oPp 提取密码:0mip 1.最简单的编译less 在安装好nodejs后,cmd 进入控制台 安装 lessc : ...
- [vijos P1035] 贪婪的送礼者
为何我要做此等弱智题,只因我太久不码代码,心有所虚… 明天的任务是,做些难题,累了就理房间,实在不行就睡觉,不要做别的事情w 目测自己做不到呢OAO program vijos_p1035; ..] ...
- UI的一些方法(按钮和线)
//设置按钮字体颜色 [self.determineBtn setTitleColor:[UIColor colorWithHexString:@"0xff9500"] forSt ...
- Visual Studio 2015 社区版.专业版.企业版[含安装密钥Pro&Ent]
社区版(Visual Studio Community 2015)可供非企业或开源开发者们免费访问: 在线安装exe:http://download.microsoft.com/download/B/ ...
- Python开发入门与实战4-模板页面
4.Django基于模板页面 在前一章中,HTML是直接被硬编码在 Python views.py代码中,如下: from django.http import HttpResponse import ...
- 利用MVVM设计快速开发个人中心、设置等模块
我们在做iOS开发过程中,静态页面的开发比开发动态页面更让我们开发者抓狂.因为动态页面通常是一个页面一种cell样式,作为开发者只需要专注于定制好一种样式之后,就可以使用数据填充出较好的界面.而静态c ...
- android_permission权限大全
访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限 获取错略位置 android.permiss ...
- ajax对象属性withCredentials
默认情况下,ajax跨源请求不提供凭据(cookie.HTTP认证及客户端SSL证明等).通过将设置ajax的withCredentials属性设置为true,可以指定某个请求应该发送凭据.如果服务器 ...
- BZOJ 1015 并查集+离线倒序
统计块个数写错了调了好久啊,BZOJ1696的弱化版本. #include <iostream> #include <cstring> #include <algorit ...