1. 程式人生 > >leetcode 算法 之 馬拉松算法(Manacher's algorithm)(未完成)

leetcode 算法 之 馬拉松算法(Manacher's algorithm)(未完成)

馬拉松 字符串 algo abc 出現 回文字 acc c# 現在

馬拉松算法:
馬拉松算法是用來計算一個字符串中最長的回文字符串(對稱字符串,如aba abba)。

首先,我們拿到一個字符串S,然後在S中的每個字符之間加#。
例如:S="abcb" T="a#b#c#b"

我們T字符串的每一個T[i]向延伸d個字符 使得 T[i-d,i+d]是一個回文字符串。你會立刻發現,d就是以T[i]為中心的最長回文字符串的長度。

我們建立一個P數組,是的P數組的長度等於T的長度,每一個P[i]的值表示對應的T[i]為中心的最大回文字符串的長度。

如下:

*************************

瞅一下P,我們立刻就能發現最長的回文字符串長度是P[6],對應字符串是"abaaba"。

你有沒有發現,加入#之後 以前的奇數回文字符串 和 偶數回文字符串都變得優雅了呢(提示:這僅僅是為了方便講解,不是算法代碼裏所必須的步驟)。

現在,想象你在回文字符串"abaaba"的中間畫一條線,你會發現P兩邊的數字也是關於這條線對稱的。不僅僅是這個字符串,你試試"aba"也是一樣的情況。
這是巧合嗎?答說是也是,說不是也不是。這只是在某種條件下才會出現的,不管怎麽樣,我們已經取得了很大的進步。

讓我們來看看更為復雜的字符串"babcbabcbaccba"。

*****************************


上圖展示一個從P基於T的生成過程,假設你已經完成P的一部分。豎實線標記的是回文字符串"abcbabcba"的正中間C,兩個豎虛線標記回文字符串的左邊界和右邊界。
你在i這個位置,且i位置關於C的鏡像位置是i‘。你應該如何能快速計算出P[i]的值呢。

我們看到,i=13,i‘=9,我們需要計算的是P[13]。

*****************************

上圖兩個綠實線所覆蓋的區域關於C對稱。我們看一下i的鏡像i‘,很顯然P[i‘]=P[i]=1。P[i]必然是1,因為

leetcode 算法 之 馬拉松算法(Manacher's algorithm)(未完成)