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

2021-10-08 23:45:32 字數 2831 閱讀 1171

問題提出

:給定乙個字串,要求其最長回文子串

例如

「aaaa」,其最長回文子串為4,即「aaaa」,

「abcd」,最長回文子串為1,

「abccb」,最長回文子串為4,即「bccb」。

如果直接對每乙個字元遍歷,分別向兩邊查詢的話,時間複雜度為o(n

2n^2

n2),效率很低。

那有沒有更高效的演算法呢。

2023年,乙個叫manacher的人發明了一種演算法,即manacher演算法,時間複雜度可以達到o(n

nn)。

演算法描述

1 、1、

1、預處理

由於回文串分為奇回文(長度為奇數)、和偶回文(長度為偶數),本因分兩種情況處理,但為了簡化這一步,我們將對原字串進行處理,使之變成奇回文。

具體做法是在每個字元左右兩邊都加上乙個特殊字元,如:

原字串為,abba,長度為4,

處理後,#a#b#b#a#,長度為9。

原字串為,aba,長度為3,

處理後,#a#b#a#,長度為7。

2 、2、

2、最長回文子串長度

我們引入乙個輔助陣列,int p[ ]p[i]表示以原字串si位置處s[i]為中心的最長回文半徑

以字串abbaf為例,預處理後字串為#a#b#b#a#f#

i       012

3456

78910

1112

arr[i] # c # a # b # b # a # f #

p[i]12

1212

5212121

在上面這個例子中,最長回文子串為abba。以s[6]為中心,其最長回文半徑為p[6]=5,所覆蓋的字串是#a#b#b#a#,對應的原始字串為abba,即最長回文子串,長度為4,可以通過5-1得到。

接下來我們來**最長回文子串長度最長回文半徑之間的關係

再看幾個例子,aba, 轉換之後為#a#b#a#,最長回文子串為aba,長度為3,最長回文半徑為p[4]=4

再如,#a#e#f#e#a#,最長回文子串為aefea,長度為5,計算得最長回文半徑為p[6]=6

我們發現,最長回文子串長度=最長回文半徑-1,即p[i]-1

事實上,的確存在這個結論。我們可以這樣理解,最長回文子串即以某一點i為中心,以p[i]為半徑所覆蓋的線段,那麼對於原始字串最長回文子串長度=p[i]*2。由於預處理後,每個字元左右都加了乙個特殊字元,所以最長回文半徑變為了原來的2倍,最長回文子串長度變為了原來的*2-1,那麼最長回文子串長度=p[i]-1

3 、3、

3、計算p陣列

現在知道了要求的最長回文子串長度與最大回文半徑p[i]有關,那麼接下來就討論最大回文半徑p[i]怎麼求。

我們設定兩個變數idmxid表示能延伸到最右端的回文子串的中心位置,mx表示該子串的最右端位置。

那麼有,mx=id+p[id]

對於i4、4、

4、參考** c++

char s[maxn]

;//原始字串

char s1[maxn]

;//預處理後字串

char p[maxn]

;//最長回文半徑

intinit()

//預處理

s1[j]

='\0'

;//處理邊界,防止越界

return j;

//返回處理後的字串長度

}int

manacher()

//計算最長回文子串長度

maxlen=

max(maxlen,p[i]-1

);}return maxlen;

//返回最長回文子串長度

}

5、5、

5、參考習題

洛谷p3805 【模板】manacher演算法

orhdu3068 最長回文

Manacher 馬拉車演算法

給定乙個字串,求出其的最長回文子串 乙個將時間複雜度優化到o n 的演算法 暴力演算法,但不是純暴力,即按照做過的事情不再去做來優化 我們知道,乙個回文串要麼是奇數的串 aba 要麼是偶數的串 abba 可以看出,乙個回文串有乙個對稱軸 對於奇數串aba來說,對稱軸就是b 而對於偶數串abba來說,...

Manacher演算法(馬拉車)

演算法總結第三彈 manacher演算法,前面講了兩個字串相演算法 kmp和拓展kmp,這次來還是來總結乙個字串演算法,manacher演算法,我習慣叫他 馬拉車 演算法。相對於前面介紹的兩個演算法,manacher演算法的應用範圍要狹窄得多,但是它的思想和拓展kmp演算法有很多共通支出,所以在這裡...

馬拉車演算法manacher

1.預處理解決奇回文和偶回文問題 比如 str bcbaa 在每個字元的開頭,結尾和中間插入乙個特殊字元 來得到乙個新的字串 b c b a a 這樣對於原來字串中的奇回文 bcb 來說,在新的字串中變成了 b c b 還是奇回文,只是回文串長度從3變成了7 注意 中 i 1 0,與1按位與,如果i...