Manacher演算法 學習總結

2021-09-27 18:46:11 字數 2510 閱讀 3089

求乙個序列的最大回文子串,我們需要需要用到manacher演算法。其作用在於能夠在o(n)的時間內求出最長回文子串,同時也能夠求出回文子串的個數。且時間效率高,**十分簡潔。

我們知道,回文子串分為奇數回文子串偶數回文子串。由於兩種情況的處理較為麻煩,我們可以考慮在期間插入字元在簡化問題。

例如例子:aba

babc

abababc

ababab

c中,如果我們隊每相鄰的兩個數之間插入字元#,我們可以得到字串:#a#

b#a#

b#a#

b#c#

\#a\#b\#a\#b\#a\#b\#c\#

#a#b#a

#b#a

#b#c

#這樣,我們就將原問題轉化為了奇數的回文子串。對於在第i

ii個位置的字元a

ia_i

ai​,我們可以求出最長的回文半徑p

ip_i

pi​.那麼我們有如下結論:

那麼我們只要完成一遍namacher演算法,就能夠得到相應的p

pp陣列解決相應的問題。現在我們我們考慮如何求解p

pp陣列。

對於manacher演算法,我們需要維護乙個擴充套件到的最右邊的回文位置mxmx

mx和回文中心idid

id。即如果當前位置為i

ii,有位置i+p

[i]i+p[i]

i+p[i]

為當前的最右位置,那麼mx=

max⁡(i

+p[i

])mx=\max(i+p[i])

mx=max(i

+p[i

]),i did

id是對應的i

ii。那麼這個演算法有什麼用呢?如圖所示:

我們根據之前對稱中心idid

id和當前位置i

ii,得到idid

id左邊與i對應的位置j

jj。j

jj的座標是:j=i

d−(i

−id)

=2×i

d−ij=id-(i-id)=2\times id-i

j=id−(

i−id

)=2×

id−i

我們會發現:

那麼在初始化時,我們就有:p[i

]=min⁡(p

[id×

2−i]

,mx−

i)p[i]=\min(p[id\times2 -i],mx-i)

p[i]

=min(p

[id×

2−i]

,mx−

i)然後我們進行暴力擴充套件即可。

當p [i

]=p[

j]p[i]=p[j]

p[i]=p

[j]時,一次的求解複雜度為o(1

)o(1)

o(1).當p[i

]!=p

[j]p[i]!=p[j]

p[i]!=

p[j]

時,一定有p[i

]+i>mx

p[i]+i>mx

p[i]+i

>mx

則更新了mxmx

mx,而m xmx

mx的更新複雜度不超過n

nn,所以時間複雜度不超過o(n

)o(n)

o(n)

.故manacher演算法的總時間複雜度為o(n

)o(n)

o(n)

.為了防止超出了字串的範圍後繼續拓展,我們應該在字串的末尾加乙個不一樣的字元即可,當時開頭也可以加乙個不一樣的字元,但需要保證開頭結尾不同。

**如下:

#include

#include

#include

using

namespace std;

const

int n =

23000000

;int p[n]

;char s[n]

, a[n]

;void

malacher

(int n)

return;}

intmain

(void)

a[n*2+

2]='*'

;malacher(2

*n+1);

int ans =0;

for(

int i=

1;i<=n*2+

1;++i)

ans =

max(ans,p[i]-1

);cout<

return0;

}

演算法學習 manacher

沒有前置知識 解決的問題 大多數都和回文串有關 例如 字串中長度最長的回文串 演算法學習 請牢記這個目的 先來講樸素演算法 從1 n,對每個字元都從其自身開始,向兩邊遞推,如果左右兩邊字元相同,範圍 1,長度 2 這樣的複雜度是n 2的 而 manacher 的優化方式和 kmp 有所類似,都是利用...

Manacher演算法 學習筆記

首先,強烈安利一篇文章,這篇文章對於 manacher 的講解本人感覺非常到位。傳送門相信大家都知道的乙個方法 列舉字串的每乙個位置作為回文子串的對稱中心,同時向左向右擴充套件,判斷是否相等,然後每次儲存之前求取的最大回文子串長度,時間複雜度為 o n 2 在列舉時,還需要考慮對奇數回文串和偶數回文...

Manacher演算法學習筆記

manacher演算法是乙個求乙個字串中最長回文連續子串行的演算法 p3805 模板 manacher 演算法 description 求最長回文子串的長度 solution 我們先引入乙個 o n 2 的做法,列舉每個字元為回文串的中心,嘗試向兩邊擴充套件,用擴充套件的最大長度更新答案。為了下文描...