最长回文子串
原题地址:最长回文子串
题目描述:
给你一个字符串 s
,找到 s
中最长的回文子串。
示例1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例2:
输入:s = "cbbd"
输出:"bb"
思路:
一读题目,就知道是典型的回文问题,今天给大家换一种方法,使用双指针的另一种典型代表——“中心扩展法”来解决该问题。核心思想是把字符串的某一位元素当做扩散中心,利用双指针向字符串首尾两端移动,若双指针指向的元素相等,则继续;否则停止,并判断当前扩散得到的字符串长度是否最大。
算法如下:
1.遍历整个字符串,令当前元素的索引值为i
,遍历范围是[0, n-1]。为何是n-1,是因为如果取最后一个元素作为扩散中心的话,无法再向右进行扩散,因此,在该情况下,最大回文子串的长度为1,和初始化相等,就不予考虑了。
2.首先考虑字符串的长度为奇数的情况,建立首尾双指针left
和right
,同时指向s[i]
。
3.建立while循环
,循环条件是比较首尾双指针指向的元素是否相同以及是否越出s
的长度界限,若相同,首指针往右移,尾指针往左移;若不相同,返回s[i+1, j]
。
4.判断当前回文子串的长度是否大于历史回文子串的长度,若大于,记录。
5.考虑字符串的长度为偶数的情况,建立首尾双指针left
和right
,分别指向s[i]
和s[i+1]
。
6.建立while循环
,循环条件是比较首尾双指针指向的元素是否相同以及是否越出s
的长度界限,若相同,首指针往右移,尾指针往左移;若不相同,返回s[i+1, j]
。
7.判断当前回文子串的长度是否大于历史回文子串的长度,若大于,记录。
8.遍历结束,返回历史最大回文长度对应的回文子串。
代码如下:
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n == 0:
return ""
# 初始化
maxPalindrome = s[0]
maxLength = 1
def centerDiffusion(i, j, s):
while i >= 0 and j < n and s[i] == s[j]:
i -= 1
j += 1
return s[i+1:j]
for i in range(n-1):
oddPalindrome = centerDiffusion(i, i, s)
evenPalindrome = centerDiffusion(i, i+1, s)
if len(oddPalindrome) > maxLength:
maxPalindrome = oddPalindrome
maxLength = len(maxPalindrome)
if len(evenPalindrome) > maxLength:
maxPalindrome = evenPalindrome
maxLength = len(maxPalindrome)
return maxPalindrome
总结
时间复杂度:外层循环 O ( n ) O(n) O(n),内层嵌套了两个并列的循环 O ( n ) O(n) O(n)。即 2 ∗ O ( n ) ∗ O ( n ) = O ( n 2 ) 2*O(n)*O(n)=O(n^2) 2∗O(n)∗O(n)=O(n2)
空间复杂度: O ( 1 ) O(1) O(1)