题目:
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
给你一个字符创s,找到最长的回文子串。假设s的最大长度为1000
Example1:
Input: "babad" Output: "bab" Note: "aba" is also a valid answer.
Example2:
Input: "cbbd" Output: "bb"
思路:
刚开始看到这个题目的时候,觉得很容易,只需要遍历字符串,使用两个for循环就能解决,将所有的子串进行对比,下面也给出了这种简单粗暴的代码。
class Solution:
def longestPalindrome(self, s: str) -> str:
if len(s) == 2:
if s[0] == s[1]:
return s
else:
return s[0]
elif len(s) == 1:
return s
elif len(s) == 0:
return ''
elif len(s) > 2:
max = 0
result = ''
for i in range(len(s)):
for j in range(i, len(s)):
temp = s[i:j+1]
temp1 = temp[::-1]
# print(temp, ',', temp1)
if temp == temp1:
if len(temp1) > max:
max, result = len(temp1), temp
else:
max, result = max, result
return result
思考:
很明显,这段算法的时间复杂度为0(n²),效率比较低。事实上也是,在使用测试数据进行测试的时候,需要的时间比较多。下面给出了改进的算法,效率提高了十倍有余。
思路:
观察解的形式,不难发现,一个回文字符串他的中间的的两个字符(当回文字符的长度是奇数的时候,那么最中间位置的两边的字符是一样)是一样的。得出一个解决方案就是,遍历每一个字符,然后对他左边,两边,右边的字符进行递归比较。代码如下
class Solution:
def get_max(self,left, right):
left = left[::-1]
minlen = len(right) if len(left) >= len(right) else len(left)
if minlen == 1:
return 2
else:
for i in range(minlen):
if left[i] == right[i]:
continue
else:
return 2*i
return 2*minlen
def longestPalindrome(self, s: str)->str:
if len(s) == 2:
if s[0] == s[1]:
return s
else:
return s[0]
elif len(s) == 1:
return s
elif len(s) == 0:
return ''
elif len(s) > 2:
max0 = 0
max1 = 0
max2 = 0
max3 = 0
max4 = 0
result = {}
for i in range(1, len(s)-1):
if s[i] == s[i-1]:
max1 = self.get_max(s[:i], s[i:])
result[max1] = s[i - int(max1 // 2):i + int(max1 // 2)]
if s[i] == s[i+1]:
max2 = self.get_max(s[:i+1], s[i+1:])
result[max2] = s[i - int(max2 // 2)+1:i + int(max2 // 2)+1]
if s[i-1] == s[i+1]:
max3 = self.get_max(s[:i], s[i+1:]) + 1
result[max3] = s[i - int(max3 // 2):i + int(max3 // 2) + 1]
if s[i-1] != s[i] and s[i] != s[i+1] and s[i-1] != s[i+1]:
max4 = 1
result[max4] = s[i]
max0 = max(max0, max1, max2, max3, max4)
return result[max0]