1. 程式人生 > >談談我對Manacher算法的理解

談談我對Manacher算法的理解

位置 直接 簡化 rar img 左右 分享圖片 [ ] 由於

Manacher算法其實是求字符串裏面最長的回文

在學習該算法前,我們應該知道回文的定義:順序讀取回文和逆序讀取回文得到的結果是一樣的,如:abba,aba。

那麽我們不難想到,在判斷一個字符串str是否為回文之前,需要判斷str中字符的個數的奇偶性。

為了簡化這一個冗雜的判斷過程,Manacher算法對字符串str進行了預處理

在每個字符之間插入一個一定不會出現的字符,如 ‘#’,‘$‘等。

技術分享圖片

為了後面我們更好地對字符串進行操作,我們可以在開頭加一個標識符,標識字符串的開頭(這裏以‘$‘為例)。

到了這一步,無論原來字符串奇偶如何,現在都變成了偶數字符串

技術分享圖片

做完預處理之後,下一步就是求取 p[ ] 數組(隨便取什麽名字都可以)

p[ i ]數組的含義是存放以 s[ i ]為中心,最長回文的單邊長度。我們來看一下下面的圖來更好地理解:

技術分享圖片

以s[ 4 ] == 2為例,s[ 4 ]左右各移動一位 → 得到字符:# 和 # 相等;s[ 4 ]左右各移動兩位 → 得到字符:1 和 2 不相等;

停止移動,因此p[ 4 ]位置該存放 2,以s[ 4 ]為中心最長回文的單邊長度(包含s[ 4 ] )。

得到 p[ ] 數組之後我們就可以很簡單地知道字符串str中的最長回文長度及最長回文了。

④ p[ ] 數組求取過程的技巧:

思考:在已經知道p [ 0 ] ~ p [ id ] 的情況下如何快速求取 p[ i ] 呢?

我們來看看下面這張圖:以 s [ id ] 為中心的最長回文能夠管轄的區域是s [ my ] ~ s [ mx ]

而 i 是落在了 my ~ mx 中。由於對稱性,能夠找到 j 使 s [ i ] == s [ j ] 同時 p [ i ] == p [ j ]

那麽這個時候,可以直接令p [ i ] = p [ j ]。

同樣地,在 id~mx 這個範圍中的p [ ] 都能通過對稱求出來。

技術分享圖片

如果 i 落在mx右邊的話,前半部分可以用對稱,後半部分只能暴力求 p [ ]啦~


以上只是自己的一些拙見,如果有不正確的地方,歡迎指出。

談談我對Manacher算法的理解