【LeetCode 中等題】3-最長迴文子串
阿新 • • 發佈:2018-11-27
宣告:
今天是中等題第3道題。給定一個字串 s
,找到 s
中最長的迴文子串。以下所有程式碼經過樓主驗證都能在LeetCode上執行成功,程式碼也是借鑑別人的,在文末會附上參考的部落格連結,如果侵犯了博主的相關權益,請聯絡我刪除
(手動比心ღ( ´・ᴗ・` ))
正文
題目:給定一個字串 s
,找到 s
中最長的迴文子串。你可以假設 s
的最大長度為 1000。
示例 1:
輸入: "babad" 輸出: "bab" 注意: "aba" 也是一個有效答案。示例 2:
輸入: "cbbd" 輸出:"bb"
解法1。從頭開始遍歷每個元素看看是不是迴文串中心,對於每個元素,它有可能是迴文串的中心(奇數個字元),也有可能和它的下一個字元構成迴文串的中心(偶數個字元),由此判斷長度是不是更長來決定是否要更新起始index,程式碼如下。
執行用時: 932 ms, 在Longest Palindromic Substring的Python3提交中擊敗了66.74% 的使用者
class Solution: def longestPalindrome(self, s): """ :type s: str :rtype: str """ if not s: return len_s = len(s) for i in range(len_s): len1 = self.helper(s,i,i,len_s) # 本身是迴文串中心的情況 len2 = self.helper(s,i,i+1,len_s) # 本身+下一個元素是迴文串中心的情況 len_m = max(len1,len2) if len_m > end-start+1: # 如果新的最長迴文串長度大於原來的就更新原迴文串始末index start = i - (len_m-1)//2 end = i + len_m//2 return s[start:end+1] # 該函式用於計算從當前元素左右擴充套件直到不是迴文串為止的index def helper(self,s,L,R,len_s): while L >= 0 and R < len_s and s[L] == s[R]: L -= 1 R += 1 return R - L - 1
解法2。還有種演算法Manacher,但我沒看太懂,而且下面的程式碼求的是最長迴文串長度,姑且看看,也許以後就懂了
def manacher(s): #預處理 s='#'+'#'.join(s)+'#' RL=[0]*len(s) MaxRight=0 pos=0 MaxLen=0 for i in range(len(s)): if i<MaxRight: RL[i]=min(RL[2*pos-i], MaxRight-i) else: RL[i]=1 #嘗試擴充套件,注意處理邊界 while i-RL[i]>=0 and i+RL[i]<len(s) and s[i-RL[i]]==s[i+RL[i]]: RL[i]+=1 #更新MaxRight,pos if RL[i]+i-1>MaxRight: MaxRight=RL[i]+i-1 pos=i #更新最長迴文串的長度 MaxLen=max(MaxLen, RL[i]) return MaxLen-1 # V 2.0 # manacher演算法 def manacher(self): s = '#' + '#'.join(self.string) + '#' # 字串處理,用特殊字元隔離字串,方便處理偶數子串 lens = len(s) f = [] # 輔助列表:f[i]表示i作中心的最長迴文子串的長度 maxj = 0 # 記錄對i右邊影響最大的字元位置j maxl = 0 # 記錄j影響範圍的右邊界 maxd = 0 # 記錄最長的迴文子串長度 for i in range(lens): # 遍歷字串 if maxl > i: count = min(maxl-i, int(f[2*maxj-i]/2)+1) # 這裡為了方便後續計算使用count,其表示當前字元到其影響範圍的右邊界的距離 else : count = 1 while i-count >= 0 and i+count < lens and s[i-count] == s[i+count]: # 兩邊擴充套件 count += 1 if(i-1+count) > maxl: # 更新影響範圍最大的字元j及其右邊界 maxl, maxj = i-1+count, i f.append(count*2-1) maxd = max(maxd, f[i]) # 更新迴文子串最長長度 return int((maxd+1)/2)-1 # 去除特殊字元
結尾
解法1:官方解法
解法2:https://segmentfault.com/a/1190000003914228 https://blog.csdn.net/asd136912/article/details/78987624