给定一个字符串,求它最长的回文子串长度,例如输入字符串'35534321',它的最长回文子串是'3553',所以返回4。

最容易想到的办法是枚举出所有的子串,然后一一判断是否为回文串,返回最长的回文子串长度。不用我说,枚举实现的耗时是我们无法忍受的。那么有没有高效查找回文子串的方法呢?答案当然是肯定的,那就是中心扩展法,选择一个元素作为中心,然后向外发散的寻找以该元素为圆心的最大回文子串。但是又出现了新的问题,回文子串的长度即可能是基数,也可能好是偶数,对于长度为偶数的回文子串来说是不存在中心元素的。那是否有一种办法能将奇偶长度的子串归为一类,统一使用中心扩展法呢?它就是manacher算法,在原字符串中插入特殊字符,例如插入#后原字符串变成'#3#5#5#3#4#3#2#1#'。现在我们对新字符串使用中心扩展发即可,中心扩展法得到的半径就是子串的长度。

现在实现思路已经明确了,先转化字符串'35534321'  ---->  '#3#5#5#3#4#3#2#1#',然后求出以每个元素为中心的最长回文子串的长度。以下给出python实现:

#!/usr/bin/python
# -*- coding: utf-8 -*- def max_substr(string):
s_list = [s for s in string]
string = '#' + '#'.join(s_list) + '#'
max_length = 0
length = len(string)
for index in range(0, length):
r_length = get_length(string, index)
if max_length < r_length:
max_length = r_length
return max_length def get_length(string, index):
# 循环求出index为中心的最长回文字串
length = 0
r_ = len(string)
for i in range(1,index+1):
if index+i < r_ and string[index-i] == string[index+i]:
length += 1
else:
break
return length if __name__ == "__main__":
result = max_substr("")
print result

功能已经实现了,经过测试也没有bug,但是我们静下心来想一想,目前的解法是否还有优化空间呢?根据目前的解法,我们求出了‘35534321‘中每个元素中心的最大回文子串。当遍历到'4'时,我们已经知道目前最长的回文子串的长度max_length是4,这是我们求出了以4为中心的最长回文子串长度是3,它比max_length要小,所以我们不更新max_length。换句话说,我们计算以4为中心的最长回文字串长度是做了无用功。这就是我们要优化的地方,既然某个元素的最长的回文子串长度并没有超过max_length,我们就没有必要计算它的最长回文子串,在遍历一个新的元素时,我们要优先判断以它为中心的回文子串的长度是否能超越max_length,如果不能超过,就继续遍历下一个元素。以下是优化后的实现:

#!/usr/bin/python
# -*- coding: utf-8 -*- def max_substr(string):
s_list = [s for s in string]
string = '#' + '#'.join(s_list) + '#'
max_length = 0
length = len(string)
for index in range(0, length):
r_length = get_length2(string, index, max_length)
if max_length < r_length:
max_length = r_length
return max_length def get_length2(string, index, max_length):
# 基于已知的最长字串求最长字串
# 1.中心+最大半径超出字符串范围, return
r_ = len(string)
if index + max_length > r_:
return max_length # 2.无法超越最大半径, return
l_string = string[index - max_length + 1 : index + 1]
r_string = string[index : index + max_length]
if l_string != r_string[::-1]:
return max_length # 3.计算新的最大半径
result = max_length
for i in range(max_length, r_):
if index-i >= 0 and index+i < r_ and string[index-i] == string[index+i]:
result += 1
else:
break
return result - 1
if __name__ == "__main__":
result = max_substr("")
print result

那么速度到底提升了多少呢,以字符串1000个‘1’为例,优化前的算法执行时间为0.239018201828,优化后为0.0180191993713,速度提升了10倍左右

/usr/bin/python /Users/hakuippei/PycharmProjects/untitled/the_method_of_programming.py
0.239018201828
0.0180191993713

python实现求最长子串长度的更多相关文章

  1. Uva 12012 Detection of Extraterrestrial 求循环节个数为1-n的最长子串长度 KMP

    题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=3163">点击打开链接 题意: ...

  2. [getLongestLength] 加和为0的最长子串长度

    点击这里查看原文 假设一个数组仅仅由1和-1组成,求该数组的和为0的最长子串的长度. 例如: {1,-1,1,-1,1,1,1} 输出:4. 昨天机试的时候做到这道题,不会做,今天思考一下. 普通的解 ...

  3. 关于求最长子串,使得最大减最小小于k的问题-以POJ4003为例

    问题 给出一个长度为\(n\)的序列\(a[i]\),有\(m\)次询问, 每次给你一个\(k\),让你求一个最长子串\([l,r]\),使得\(max_l^r\{a_i\}-min_l^r\{a_i ...

  4. squee_spoon and his Cube VI---郑大校赛(求最长子串)

    市面上最常见的魔方,是三阶魔方,英文名为Rubik's Cube,以魔方的发明者鲁比克教授的名字命名.另外,二阶魔方叫Pocket Cube,它只有2*2*2个角块,通常也就比较小:四阶魔方叫Reve ...

  5. Leetcode3--->无重复字符的最长子串长度

    题目:给定一个字符串string,找出string中无重复字符的最长子串. 举例: Given "abcabcbb", the answer is "abc", ...

  6. Python [习题] 求最长共同子串

    s1 = 'abcdefg's2 = 'defabcdoabcdeftw's3 = '1234a's4 = 'wqweshjkb's5 = 'defabcd's6 = 'j' 求 s1.s3.s4.s ...

  7. leetcode3:不重复的最长子串长度

    package hashmap; import java.util.HashMap; import java.util.Map; public class hashmap { public stati ...

  8. LeetCode03 - 无重复字符的最长子串(Java 实现)

    LeetCode03 - 无重复字符的最长子串(Java 实现) 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/longest-substri ...

  9. leecode第三题(无重复字符的最长子串)

    class Solution { public: int lengthOfLongestSubstring(string s) { int len=s.size(); ||len==)//边界 ret ...

随机推荐

  1. Asp.Net Web API中使用Session,Cache和Application的几个方法

    在ASP.NET中,Web Api的控制器类派生于ApiController,该类与ASP.NET的Control类没有直接关系,因此不能像在Web MVC中直接使用HttpContext,Cache ...

  2. Python云端系统开发入门——框架基础

    Django框架基础 这是我学习北京理工大学嵩天老师的<Python云端系统开发入门>课程的笔记,在此我特别感谢老师的精彩讲解和对我的引导. 1.Django简介与安装 Django是一个 ...

  3. ImportError: No module named 'request'

    使用系统自带的Python 2.7执行python时出现ImportError: No module named 'request'这样的报错,这是系统自带的Python没有requests库,这里可 ...

  4. xCode8以及iOS10 的新特性

    其他:ios10中 适配问题(1.系统判断方法失效:2.隐私数据的访问问题:3.UIColor 问题4.真彩色的显示5.ATS问题6.UIStatusBar问题7.UITextField8.UserN ...

  5. [数据结构]C语言栈的实现

    有始有终,所以我准备把各种数据结构都讲一次,栈也分顺序存储和链式储存,这里我们选择链式存储来讲,顺序存储没有难度(链式其实也是) 作为数据结构中最简单的栈,这里不会说太多,首先考虑一下下面的model ...

  6. 669. Trim a Binary Search Tree

      Given a binary search tree and the lowest and highest boundaries as `L`and `R`, trim the tree so t ...

  7. ArcGIS 网络分析[1.1] 创建用于网络分析用的线类型shp文件[这个太基础了吧!]

    具体的准备,在上一篇就说过了,不再赘述. 阅读本篇前,需要的预备知识是:ArcGIS创建各种矢量数据的方法,了解地理坐标与投影坐标 本篇只创建单一的线数据,至于点数据,以后进行复杂的网络分析时再添加进 ...

  8. bzoj 4012: [HNOI2015]开店

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  9. openldap 编译报错MozNSS not found

    openldap 编译报错 1)报错 MozNSS not found - please specify the location to the NSPR and NSS header files i ...

  10. Jenkins远程部署SpringBoot应用

    一般Web工程通过Jenkins远程部署到Tomcat,可以采用Maven的tomcat-maven-plugin插件进行部署.最近接触到Spring Boot工程的部署,由于Spring Boot应 ...