給你乙個字串 s,找到 s 中最長的回文子串。
示例 1:
輸入:s = 「babad」
輸出:「bab」
解釋:「aba」 同樣是符合題意的答案。
示例 2:
輸入:s = 「cbbd」
輸出:「bb」
示例 3:
輸入:s = 「a」
輸出:「a」
示例 4:
輸入:s = 「ac」
輸出:「a」
首先來說回文串的性質:
1.回文串是根據中心點擴散而來
當回文串長度為奇數時,那麼中心點只有乙個,例如"abcdcba",那麼中心點就是d,中心點兩側的呈對稱,確定中心點(中點)後可以用棧來解決。
當回文串長度為偶數時,那麼中心點有兩個,例如「abcddcba」,那麼中心點就是dd,中心點兩側呈對稱,也可以用棧來解決。
由以上的性質可以通過遍歷中心點然後找對稱與否來確定回文串
2.根據性質一我們反推,對於乙個回文串,刪掉他的第乙個字元和最後乙個字元,仍是回文串。如果不是回文串,那麼對稱地加字元肯定也不是回文串。
解題思路:
1.中心點擴散,根據性質一可以知道,中心點就兩個可能,乙個是只有乙個點,另乙個是有兩個點。
畫個矩陣來說明。
例子:babad
ai,j表示從s[i:j+1],我們根據性質一可以寫出:
若ai,j不為回文串,那麼a(i-1),(j+1)肯定也不是回文串,在矩陣上的表示就是右斜上的字串。
class
solution
:def
longestpalindrome
(self, s:
str)
->
str:
l =len(s)
result_left, result_right =0,
0for i in
range
(l):
left, right = i, i +
1# 從兩個字母的情況開始,往右上角加
# 首先判斷一開始的是不是回文,如果是,則繼續,如果不是直接跳出,因為之後在這個斜方向不會出現回文
while left >=
0and right <= l:
temp = s[left: right +1]
if temp != temp[::
-1]:
break
elif right-left > result_right - result_left:
result_right, result_left = right, left
right +=
1 left -=
1# 從對角線開始向斜方向運動
if i >0:
left, right = i -
1, i +
1while left >=
0and right <= l:
temp = s[left: right +1]
if temp != temp[::
-1]:
break
elif right - left > result_right - result_left:
result_right, result_left = right, left
right +=
1 left -=
1return s[result_left: result_right+
1]
時間複雜度為o(n^2)
空間複雜度為o(1)
有個優化的地方就是,不要整個擷取來判斷為回文串,只用看之前是否為回文串且新加入的頭尾是否相等就可以。
方法二:動態規劃
大佬題解
5 最長回文子串
給定乙個字串s,找到s中最長的回文子串。你可以假設s長度最長為1000。示例 輸入 babad 輸出 bab 注意 aba 也是有效答案示例 輸入 cbbd 輸出 bb 方法1 用馬拉車演算法 字串動態規劃 來求最長回文子串時間複雜度可以達到o n 但是部落格裡面有個小失誤 這個id應該不是最大回文...
5 最長回文子串
給定乙個字串s,找到s中最長的回文子串。你可以假設s的最大長度為1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb class solution def longestpalindrome self,s k len s olist...
5 最長回文子串
給定乙個字串s,找到s中最長的回文子串。你可以假設s的最大長度為 1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb 這道題比較船艇的應該是dp求法,但鄙人的dp特別特別的差勁。所以我選用中心擴充套件演算法,掃一遍所有節點,把被掃...