最長回文子串,即正反讀起來都一樣,例如「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 為中...