最長回文子串(馬拉車演算法)

2021-09-26 13:39:58 字數 2450 閱讀 2264

最長回文子串,即正反讀起來都一樣,例如「ababa」。manacher algorithm演算法利用了回文的重複特性,讓時間複雜度降為了o(n)。

馬拉車演算法詳解:

改造字串,在中心擴充套件法中,要求區分字串長度為奇數或偶數的情況,我們這裡對字串進行簡單的改造,讓字串變成奇數便於處理。例:「ababad」 ---->「a#b#a#b#a#d」。為了在檢測回文子串的時候避免判斷越界,我們可以在開頭和結束新增兩個不同的字元---->"$a#b#a#b#a#d^"(也不可不做這一步,如果不在開頭和結束新增兩個不同的字元的話,就需要在檢測回文子串的時候檢測開頭和結尾)

為了能夠充分利用回文子串的重複性質,我們可以將字串中每個字元的回文半徑存如乙個陣列p中

這樣就將問題轉換為了求陣列p中的最大值所在的下標和值。但在實際操作中我們並不這樣做,是動態的尋著陣列p的最大值,即一邊寫入一邊檢測,而不是等陣列p填充完畢後再去尋找陣列p的最大值。因為字串"a#a"和"#a#「雖然第乙個字串的」#「和第二個字串的"a"的回文半徑是相同的,但是,顯而易見,在去掉」#「後 乙個是"aa」,乙個是"a"。

關於如何填充陣列p

先設定兩個變數,馬拉車演算法就是在動態的更新這兩個變數。

center:是最大回文子串的中心位置

mx_right:是最大回文子串所能覆蓋的最右端的位置。

共分為兩種情況:

當 i < mx_right時:即i位於目前的最大回文子串max_str中。那麼我們根據回文的重複特性,取檢查j = 2 * center - i(j為i以center為中心的對稱點)。如果p[j] < mx_right - i 說明以j為中心的回文子串依然位於目前的最大回文子串max_str,很具重複特性可以知道此時p[i] == p[j]。如果p[j] >= mx_right - i,此時只能保證到i的回文子串到mx_right這位置是依然滿足的,這裡別無他法,只能暴力取匹配mx_right外面的,直到失配,然後在根據大小判斷是否更新最大回文子串max_str

當i >= mx_right時:此時不能充分利用回文子串的重複特性,只能暴力匹配。

def

longestpainromedon

(s:str):

iflen

(s)<1:

return s

new_str =

'$'+

'#'.join(s)

+'^'

#避免判斷越界

center =

1#最長回文子串中心位置

mx_right =

1#最長回文子串最右面覆蓋的位置

max_str = new_str[1]

#最長回文子串

p =[0

]*len(new_str)

#回文子串半徑表列

for i in

range(1

,len

(new_str)-1

):j =

2*center - i

if i < mx_right:

if p[j]

< mx_right - i:

p[i]

= p[j]

else

: k = mx_right+

1while new_str[k]

== new_str[

2*i - k]

: k +=

1 k -=

1 p[i]

= k - i

cur_str = new_str[i - p[i]

:i + p[i]+1

].replace(

'#','')

iflen

(cur_str)

>

len(max_str)

: max_str = cur_str

center, mx_right = i, k

else

: k =

0while new_str[i - k -1]

== new_str[i + k +1]

: k +=

1 p[i]

= k cur_str = new_str[i - p[i]

:i+p[i]+1

].replace(

'#','')

iflen

(cur_str)

>

len(max_str)

: max_str = cur_str

center, mx_right = i, k + i

return max_str

**如上,此**時完全照演算法來的,其他的部落格的**我想應該是有所優化,導致我一開始有點懵。

最長回文串(馬拉車演算法)

最長回文子串 manacher演算法 馬拉車演算法 馬拉車演算法需要計算以每個字元為中心的回文串半徑。並記錄最右邊界 馬拉車演算法基於這樣乙個事實,從回文串的中心到兩邊是對稱的,意味著以兩邊對稱的字元為中心的回文串半徑相等 在不超過最右邊界的情況下,如果超出就需要擴充套件搜尋 public stri...

最長回文串 馬拉車演算法

有兩個長度均為n的字串a和b。可以從a中選乙個可以為空的子串a l1 r1 b中選乙個可以為空的子串b l2 r2 滿足r1 l2,然後把它們拼起來 a l1 r1 b l2 r2 求用這樣的方法能得到的最長回文串的長度。注意 求的不是本質不同的回文串個數哦!解題報告 找兩個之間的最長回文串,只不過...

Manacher馬拉車演算法求最長回文子串

終於把馬拉車演算法搞明白了!趕緊記錄一下,以後忘記了還能再回憶起來。這個演算法用於查詢乙個字串的最長回文子串 馬拉車演算法依次給陣列p i 賦值,馬拉車演算法的本質就是在每次給陣列p i 賦值時嘗試進行偷懶 例如,當要給p 6 賦值時,前面分別以 p 0 p 1 p 2 p 3 p 4 p 5 為中...