题目在leetcode上的链接为:
https://leetcode-cn.com/problems/longest-palindromic-substring/
题目描述
解题思路
首先要理解什么是回文字符串,回文字符串是指正着读和反着读都一样的字符串,如 ababa,它具有对称性。因此每一个回文字符串都存在一个对称中心,离对称中心向左和向右的相同距离位置的字符都是相同的,因此可以使用中心展开法来解题。
中心展开法是指按照指定的中心字符c分别向左右两边进行展开,首先同时向左和向右移动一步,并比较左右两处的字符是否相同,如果相同再继续向左和向右移动,直到左右两处的字符不相同或者不存在为止,此时就找到了以该字符c为中心的最长回文子串。
比如对于字符串 s=“cbaba”,我们要寻找以 s[2]=‘a’ 这个字符为中心的回文子串的步骤为:
1.以索引号2为中心,向左和向右分别移动一步,判断s[2]的左右两边的字符s[1],s[3]是否相同,发现s[1]=s[3]=‘b’
2.以上一步的索引号开始继续分别向左和向右移动一步,因此判断s[0],s[4]是否相同,发现s[0]!=s[4],则已寻找到以s[2]为中心字符的最长回文子串为 “bab”
当回文字符串的长度为奇数时,它的中心为一个字符;
当回文字符串的长度为偶数时,它的中心在正中间的两个字符之间,为了方便理解,可以当做它的中心为中间的两个相同的字符。
因此对于一个给定的字符串要求它的最长回文子串,我们可以遍历所有可能的回文子串的中心,最后找出最长的回文子串即可。设给定的字符串的长度为 n,由于我们不知道它的回文子串的长度为奇数还是偶数,因此需要遍历的所有中心的数目为 2n-1。
比如给定字符串 “baba”(长度为n),那么我们需要遍历的其回文子串的长度为奇数的中心为 b a b a(数目为n),而我们需要遍历的其回文子串的长度为偶数的中心为 ba ab ba(数目为n-1),因此我们需要遍历的中心的数目为 2n-1。
复杂度分析:
由于我们需要遍历的中心的数目为 2n-1,而对于每个中心,我们需要使用中心展开法求取对应的最长回文子串,每次进行中心展开法的时间复杂度为 o(n),因此整个算法的时间复杂度为 o(n2)。
空间复杂度为 o(1)。
python代码:
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
if s == None or len(s) == 0:
return ""
start = 0
end =0
for i in range(len(s)):
len1 = self.expandAroundCenter(s, i, i) # 中心为1个字符的回文子串
len2 = self.expandAroundCenter(s, i, i + 1) # 中心为2个字符的回文子串
maxLen= max(len1, len2)
if maxLen > (end - start + 1):
start = i - (maxLen - 1) // 2
end = i + maxLen // 2
return s[start : end + 1]
def expandAroundCenter(self, s, left, right):
"""
:type s: str
:type left: int
:type right: int
:rtype: int
"""
l = left
r = right
while l >= 0 and r < len(s) and s[l] == s[r]:
l = l - 1
r = r + 1
return r - l - 1