高效的求最長回文子串的演算法 Manacher

2021-08-20 01:11:23 字數 2044 閱讀 6087

gdoi市選出了一道關於manacher的題目,於是打算學一下,但因為網路流鴿了一陣,最近才學完,學完後表示複雜度有點迷。

manacher,俗稱馬拉車,是由一位名叫manacher的人與2023年提出的,這個演算法讓求最長回文子串的複雜度從o(n^2)下降到了o(n)。

先從n方演算法說起,n方演算法是每一位都向兩邊擴充套件,直到不回文。這個演算法只是對當前位置進行操作,而manacher演算法將前面算出的值進行記錄,用於後續的處理,從而降低複雜度。

我們平時用n^2演算法處理的時候就會考慮到乙個問題,就是乙個回文串的長度,如果是像aaa一樣的長度為奇數的串,它的中心是乙個字元;如果是像abba一樣長度為偶數的串,它的中心在兩個字元中間,這樣比較難處理。所以manacher演算法會在乙個字串每兩個字元中間以及字串頭尾插入『#』(也可以是其他的,有沒有出現在原字串中其實無所謂)。

如:abcdcba會變為#a#b#c#d#c#b#a#。

這裡我們引入乙個陣列p,p[i]表示以i為中心的最長回文串的半徑長度。我們用**舉個例子:s#

a#b#

a#b#

a#b#

a#p1

2141

6181

6141

21而更神奇的是以s[i]為中心的回文串長度就是p[i]-1。

我們需要記錄的除了p陣列,還有在現在已知(即之前處理過的)的所有回文串中右邊界最右的那個回文串c的中心位置mid以及其長度len(記錄其右邊界也可)。

設我們即將處理的位置為i,i關於mid的對稱點為j,那麼:

如果i > mid+len-1

即i在回文串c右邊界的右邊,沒有任何先前的資料可以利用,所以p[i]=1,直接暴力求p[i]。

如果j-p[j]+1 >= mid-len+1,

即以j為中心的最長回文串(下圖紅色部分)在回文串c內,則以i為中心的最長回文串(下圖藍色部分)一定也在該字串內,那麼就有p[i]=p[j],如下圖。

如果j-p[j]+1 < mid-len+1,

即以j為中心的最長回文串(下圖紅色部分)有一部分在回文串c外,則以i為中心的最長回文串(下圖藍色部分)至少有一部分可以確定(下圖綠色部分),那麼我們可以直接從確定的部分拓展算出p[i],這裡p[i]一定小於p[j]。

上面是乙個理解演算法的過程,事實上並不用如此複雜的操作。另外有乙個小技巧,可以在字串最前端插入乙個』$』,在字串最末端插入乙個』\0』,並以此來完成對回文串邊界的判斷,所以插入的可以不是上述的兩個字元,但是一定不能出現在原字串中。

那麼,上**:

#include

#include

#include

using

namespace

std;

const

int maxn=11000005;

char c[maxn],s[maxn*2+1];

int lenc,lens;

int p[maxn*2+1],mid,len,maxlen;

int minn(int a,int b)

int maxx(int a,int b)

void init()

s[lens++]='\0';

memset(p,0,sizeof(p));

}int main()

//雖然看上去會讓演算法退化但是演算法優啊

if (i+p[i]>mid+len)

//更新mid和len

maxlen=maxx(maxlen,p[i]-1);

}printf("%d",maxlen);

return (0-0);

}

manacher演算法 O n 求最長回文子串

樸素的做法是求出以每個字元為中心的回文串長度,複雜度為 而manacher演算法可以在o n 時間內求解,奇數長度和偶數長度可以統一處理。根據回文串的對稱性,避免了大量不必要的比較。處理技巧 相鄰的字元之間插入乙個分隔符,串的首尾也要加,以 為例,則長度為n的字串經過處理之後變成2n 1奇數長度的字...

求最長回文子串 Manacher 演算法

給定乙個字串,求出其最長回文子串。例如 1 s abcd 最長回文長度為 1 2 s ababa 最長回文長度為 5 3 s abccb 最長回文長度為 4,即 bccb。以上問題的傳統思路大概是,遍歷每乙個字元,以該字元為中點向兩邊查詢。其時間複雜度為 o n2 很不高效。1975 年,乙個叫 m...

求最長回文子串 ManaCher演算法

最長回文子串 求任一既定字串中,回文子串的最長長度 這是最容易想到的辦法。先遍歷獲得字串的所有子串,再對每個子串判斷其是不是回文串。對於長度為n的字串,子串個數為n n 1 2,加上對每個子串進行判斷,這種解法的時間複雜度為o n 3 就不寫了,下面重點介紹manacher演算法 由回文的定義可以推...