LeetCode 5.最长回文子串
题目:
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
思路
首先要知道什么是回文数,回文数就是正反都一样,所以,这题目的解题思路要围着str正反比较。
先不考虑最优解,最直接的方法就是依次比较各个字符区间是否为正反相等回文数,最后判断大小返回最大值子串即可。
方法一:
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
result = []
length = len(s)
for i in range(0,length):
substr=s[i:length] #从左边开始依次赋值
tmpStr=substr[::-1] #取反
subLength = len(substr)
for i in range(0,subLength):
if substr[0:subLength-i] == tmpStr[i:subLength] :
res=substr[0:subLength-i] #正反相等,取当前值并塞到array里面
result.append(res) #result添加回文数
break
resStr = ''
for i in range(0,len(result)): #数组内回文数元素长度判断,返回最大长度元素
if(len(result[i]) > len(resStr)):
resStr = result[i]
return resStr
执行用时 :2652 ms, 在所有 Python 提交中击败了42.16%的用户
内存消耗 :14.4 MB, 在所有 Python 提交中击败了13.04%的用户
-- 不要在意这些细节,这个是比较笨了点,但是最直观,😄
方法二:
方法一,依次遍历比较的方式是比较浪费的,有啥办法可以优化呢?
参考了一下大大们的解法,中心扩展算法:
中心扩展算法就是通过回文中心向两边扩展找到最大回文长度,这个方法比较巧妙,遍历次数不再是方法一的n^2
class Solution:
def longestPalindrome(self, s):
start = end = 0
for i in range(len(s) - 1):
lenOne = self.expandAroundCenter(s, i, i) #中心为一个,"abcba"
lenTwo = self.expandAroundCenter(s, i, i+1) #中心为两个,"abba"
lenMax = max(lenOne, lenTwo)
if lenMax > (end - start): #取当前回文长度最大值并赋边界.
start = i - (lenMax-1)/2
end = i + lenMax/2
return s[start:end+1]
def expandAroundCenter(self, s, left, right) :
while left >= 0 and right < len(s) and s[left] == s[right]: #while依次扩展遍历
left -= 1
right +=1
return right - left - 1
执行用时 :640 ms, 在所有 Python 提交中击败了79.92%的用户
内存消耗 :12.7 MB, 在所有 Python 提交中击败了13.04%的用户
Knowledge, like candlelight, can illuminate a person and countless people.