leetcode 求一个字符串的最长回文子串
最长回文子串问题:给定一个字符串,求它的最长回文子串长度。如果一个字符串正着读和反着读是一样的,那它就是回文串。
最容易想到的办法是枚举出所有的子串,然后一一判断是否为回文串,返回最长的回文子串长度。不用我说,枚举实现的耗时是我们无法忍受的。那么有没有高效查找回文子串的方法呢?答案当然是肯定的,那就是中心扩展法,选择一个元素作为中心,然后向外发散的寻找以该元素为圆心的最大回文子串。但是又出现了新的问题,回文子串的长度即可能是奇数,也可能好是偶数,对于长度为偶数的回文子串来说是不存在中心元素的。那是否有一种办法能将奇偶长度的子串归为一类,统一使用中心扩展法呢?它就是 manacher 算法,在原字符串中插入特殊字符,例如插入 #后原字符串变成'#3#5#5#3#4#3#2#1#'。现在我们对新字符串使用中心扩展发即可,中心扩展法得到的半径就是子串的长度。
现在实现思路已经明确了,先转化字符串'35534321' ----> '#3#5#5#3#4#3#2#1#',然后求出以每个元素为中心的最长回文子串的长度。以下给出 python 实现:
#!/usr/bin/python
# -*- coding: utf- -*- def max_substr(string):
s_list = [s for s in string]
string = '#' + '#'.join(s_list) + '#'
max_length =
length = len(string)
for index in range(, 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 =
r_ = len(string)
for i in range(,index+):
if index+i < r_ and string[index-i] == string[index+i]:
length +=
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)
Leetcode上原题解答如下:
class Solution:
# 从中心向外扩散
def helper(self, s, l, r):
while l >= 0 and r < len(s) and s[l] == s[r]:
l -= 1; r += 1
return s[l+1:r]
# O(n^2)时间复杂度方法
def longestPalindrome(self, s):
res = ""
for i in range(len(s)):
# 单核回文如 "aba"
tmp = self.helper(s, i, i)
if len(tmp) > len(res):
res = tmp
# 双核回文如 "abba"
tmp = self.helper(s, i, i+1)
if len(tmp) > len(res):
res = tmp
return res 转自:https://www.cnblogs.com/dahu-daqing/p/9302681.html
leetcode 求一个字符串的最长回文子串的更多相关文章
- hdu3068 求一个字符串中最长回文字符串的长度 Manacher算法
最长回文 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 计算字符串的最长回文子串 :Manacher算法介绍
转自: http://www.open-open.com/lib/view/open1419150233417.html Manacher算法 在介绍算法之前,首先介绍一下什么是回文串,所谓回文串,简 ...
- LeetCode之“字符串”:最长回文子串
题目要求: 给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串.例如,给出字符串 "abcdzdcab",它的最长回文子串为 & ...
- Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法)
Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法) Given a string s, find the longest pal ...
- 【回文字符串】 最长回文子串O(N) Manacher算法
原理讲的清晰:Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串 注意: ①动态生命P[]和newStr数组后,不要忘记delete[] //其实这是基本的编码习惯 ②最终 ...
- Manarcher 求 字符串 的最长回文子串 【记录】
声明:这里仅仅写出了实现过程.想学习Manacher的能够看下这里给出的实现过程,算法涉及的一些原理推荐个博客. 给个链接 感觉讲的非常细 引子:给定一个字符串s,让你求出最长的回文子串的长度. 算法 ...
- (转载)Manacher'sAlgorithm: O(n)时间求字符串的最长回文子串
以下内容转载自:传送门 源于这两篇文章: http://blog.csdn.net/ggggiqnypgjg/article/details/6645824http://zhuhongcheng.wo ...
- LeetCode(5):最长回文子串
Medium! 题目描述: 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 长度最长为1000. 示例: 输入: "babad" 输出: "bab&quo ...
- [LeetCode] 5. Longest Palindromic Substring 最长回文子串
Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...
随机推荐
- Oracle中查询表中数据的上次更新时间
目前找到的是以下方式,但是这种方式在表的数据量比较大的时候效率会比较慢. select to_char(scn_to_timestamp(max(ora_rowscn)),'YYYY-MM-DD HH ...
- hibernate的详解
一,环境的搭建 1)创建maven项目 2)导入依赖的jar包.pom.xml和创建实体类User <?xml version="1.0" encoding="UT ...
- 1121 Django基本
目录 Django前戏 一.课程导读 1.web应用 2.c/s b/s 架构 3.Python Web框架 二.原生socket服务 三.http协议 什么是http协议 四大特性 http工作原理 ...
- 移动Web前端开发 3移动web开发现状
移动端的手机浏览器内核一般都是Webkit内核,只需要适配Webkit就可以了 适配问题 屏幕尺寸不一
- halcon基础数据类型详解
#if defined(__CHAR_UNSIGNED__) || defined(__sgi) #define INT1 signed char /* integer, signed 1 Byte ...
- python中的几种数据类型(一)
一.整型(数字) python2中有长整形long python3 中全都是整型 int n = 56 print(n.bit_length()) # 0011 1000 # 12 ...
- Tarjan算法【阅读笔记】
应用:线性时间内求出无向图的割点与桥,双连通分量.有向图的强连通分量,必经点和必经边. 主要是求两个东西,dfn和low 时间戳dfn:就是dfs序,也就是每个节点在dfs遍历的过程中第一次被访问的时 ...
- P2272 [ZJOI2007]最大半连通子图 tarjan+DP
思路:$tarjan+DP$ 提交:1次 题解:首先对于一个强连通分量一定是一个半连通分量,并且形成的半连通分量的大小一定是它的$size$,所以我们先缩点. 这样,我们相当于要在新的$DAG$上找一 ...
- json 文件读写
#coding=utf- import json data ={","version":"0.0.0","desc":{" ...
- React前端开发环境搭建
先,我们需要明确的是React和很多前端框架一样,底层都还是js以及html,即便它有着看似特殊的jsx语法. 我们要在服务端运行js,就需要依赖一个环境,和运行war包需要tomcat一类中间件一样 ...