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 ...
 
随机推荐
- 《流畅的Python》Data model(数据/对象模型)
			
第一章 Data model ⚠️整本书都是讲解Data model,第一章是一个概述. ⚠️不适合初学者.因为special method和meta programming技巧只是Python代码的 ...
 - Flask实现简单的群聊和单聊
			
Flask是使用python写的一个简单轻量级的框架,今天我们使用Flask实现一个简单的单聊和群聊功能 . 主要思路 : 前端登录聊天室,聊天室信息包含用户的登录信息,相当于一个登录功能,会把这个信 ...
 - 「ZJOI2014」力 FFT
			
FFTl裸题,小于的部分直接做,大于的部分倒序后再做就行了. #include <bits/stdc++.h> using namespace std; const int MAXN = ...
 - SqlBulkCopy插入时:来自数据源的 String 类型的给定值不能转换为指定目标列的类型 int。 ---> System.FormatException: 将参数值从 String 转换到 Int32 失败。 ---> System.FormatException: 输入字符串的格式不正确。
			
偶尔间看到的 记录下:https://bbs.csdn.net/topics/390430064
 - HR# 5题解
			
T1 我傻了 前20个数暴力开桶记录,后面的每次暴力统计. #include<bits/stdc++.h> #define R register int using namespace s ...
 - 获取select框下option所有值
			
document.getElementById('roomId').options[0].value;获取第一个值 var roomIds = $("#roomId option" ...
 - CF #589 (Div. 2) D. Complete Tripartite 构造
			
这个 D 还是十分友好的~ 你发现这 $3$ 个集合形成了一个环的关系,所以随意调换顺序是无所谓的. 然后随便让 $1$ 个点成为第 $2$ 集合,那么不与这个点连边的一定也属于第二集合. 然后再随便 ...
 - qemu for win64 下载
			
下载地址:https://qemu.weilnetz.de/w64/ 安装完成后,将安装目录加入到系统环境变量.
 - jira默认是jira_user用户组的用户有登录jira的权限
			
场景描述: 今天给jira新建了几个用户组,看着英文的jira_user和jira_developer有点多余,所以就给删掉了.然后后面新建了开发人员和测试人员用户组,进行了人员分配和项目分配,可是突 ...
 - kubernetes案例 tomcat+mysql
			
该文章参考<kubernetes 权威指南> 环境: [root@master tomcat-mysql]# kubectl get nodesNAME STATUS AG ...