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 ...
随机推荐
- 剑指Offer的学习笔记(C#篇)-- 孩子们的游戏(圆圈中最后剩下的数)
题目描述 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指 ...
- Java锁--非公平锁
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3496651.html 参考代码 下面给出Java1.7.0_40版本中,ReentrantLock和AQ ...
- 转 java 中int String类型转换
转自licoolxue https://blog.csdn.net/licoolxue/article/details/1533364 int -> String int i=12345;Str ...
- pandas处理json脱坑(二)--jsonError: Expecting ',' delimiter: line 1 column 2674
Expecting ',' delimiter: line 1 column 2674 json_dict = json.loads(row[json_columns].replace("' ...
- 关于npm audit fix
https://blog.csdn.net/weixin_40817115/article/details/81007774 npm audit : npm@5.10.0 & npm@6,允许 ...
- Oracle - 特殊字符问题
Oracle更新表字段或者查询表字段时内容中含有特殊字符&的解决方法 现象 解决方式 1. 字符串拼接 UPDATE T_MENU_INFO SET menu_code='/ABeptjk/g ...
- Oracle 物理结构(一) 文件-Inventory
一.Inventory的定义与作用 oraInventory存放的是Oracle软件安装的目录信息,Oralce的安装升级都需要用到这个目录,来看看Oracle文档中对这个目录的一点说明:All Or ...
- AtCoder Beginner Contest 132
目录 Contest Info Solutions A. Fifty-Fifty B. Ordinary Number C. Divide the Problems D. Blue and Red B ...
- 关于pycharm+opencv没有代码提示的问题解决方法记录
代码可以看出实际我们引入的应该是cv2.cv2下面. 所以我们代码只需要import cv2.cv2 as cv 即可. 记着要重新启动下pycharm哦. 可以参考: https://blog.cs ...
- 爬虫之操作excel
几种常用模块的使用方法 注释:Excel 2003 即XLS文件有大小限制即65536行256列,所以不支持大文件,而Excel 2007以上即XLSX文件的限制则为1048576行16384列 下面 ...