題目
給定一個字符串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。
示例 1:
輸入: “babad”
輸出: “bab”
注意: “aba” 也是一個有效答案。
示例 2:
輸入: “cbbd”
輸出: “bb”
來源:力扣(LeetCode)
人生苦短,我用python!簡單的思路最適合大多數人!
python的精髓在於簡單,靈活,用少的代碼完成別的語言相同的工作!
最長回文字符串,我們看到這道題目,首先想到的是我們需要哪些數據,怎么操作!
數據
- 待處理的字符串,官方會給;
- 用來存儲當前最長回文字符串的變量,控制子串長度的索引變量;
- 一些其他的中間變量;
思路
做過判斷一個字符串是否是回文字符串的那道題時我們就知道,從中心向兩邊擴展依次比較對稱位置是否相等就可以了。
從第一個字符往后遍歷,把每個字符都當作中心去向兩邊擴散,當碰到邊界停下;
兩種情況
- 子串的形式為 ddbaabdd
- 子串的形式為 ddbabdd
邊界
無論兩種情況的哪一種,邊界都是相同的, 即為下面while循環的條件
- 邊界1是當控制子串的索引變量向左向右有一個碰到母串的邊了;
- 邊界2是字串在擴散的過程中,左邊字符不等於右邊字符,這樣就不是回文字符串了;
class Solution:
def longestPalindrome(self, s: str) -> str:
temp, max_p, length = "", "", len(s) # 初始化一些要用的數據
for index in range(length): # 把每個字符都當作中心
index_left, index_right = index, index
def compare(l, r): # 中心向兩邊擴散,兩種形式的邊界相同,所以一個函數搞定!
while l != -1 and r != length and s[l] == s[r]: # 邊界
l, r = l-1, r+1 # 擴散
return s[l+1:r] if l == -1 or r == length else s[l+1:r] # 因為不同的邊界條件返回的子串索引取值是有規律的!
temp = compare(index_left, index_right) # 判斷形式1是否存在
max_p = temp if len(temp) > len(max_p) else max_p # 判斷是否比當前的回文字符串更長
try:s[index+1]
except:continue
if s[index] == s[index+1]: # 判斷形式2是否存在
left, right = index, index + 1
temp = compare(left, right) # 擴散
max_p = temp if len(temp) > len(max_p) else max_p # 判斷是否比當前的回文字符串更長
return max_p # 返回最長回文字符串
代碼解讀:
max_p 是用來存放當前最長的回文子串;
compare函數,因為子串的形式只有兩種,並且兩種的邊界都相同,那我們可以把兩種給統一起來,用一個compare函數調用兩次來完成;
try和except用異常捕獲來判斷當前字符的右面是否還有字符;當然也可以用當前字符索引和母串長度的關系來判斷;