1. 程式人生 > >manacher算法處理最長的回文子串(一)

manacher算法處理最長的回文子串(一)

字母 .cn ddc 還要 自己 它的 nac 回文串 ima

引言

相信大家都玩過折疊紙張,如果把回文串相當於折疊一個A4紙,比如ABCDDCBA就是沿著中軸線(D與D之間)對折重合,那麽這個就是一個回文串。或者是ABCDEDCBA的中軸線就是E,那麽沿著中軸線對折也是重合的,所以這個字符串也是一個回文串。

   判斷一個字符串中的最長回文子串,我們可以對每個字符的兩邊進行比較,還是如何ABCDEDCBA,在A,B,C,D分別為中心軸向兩邊擴展的回文子串長度都是1,就是它自己本身,當掃描以E為中心軸時,那麽這個回文的最長子串時9,也就是這個字符串本身。然而當用相同的方法處理ABCDDCBA時,分別以A,B,C,D為中心軸向兩邊擴展,得到的最長回文子串的長度是1,實際上最長的回文子串卻是ABCDDCBA,就是它自己本身。

  為了解決以上的問題,我們對原來的子串就行填充,比如用‘#‘來填充,其實任意字符都是可以的。這樣原來為N長度的字符串變成了2*N+1的長度。例如ABCDDCBA為例子,填充完新的字符串為#A#B#C#D#D#C#B#A#。這樣根據剛才的方法從左往右,以每個字符為中心軸擴展。得到以第5個‘#‘為中心軸,向兩邊擴展掃描時,這個回文子串為最大回文子串,即本身。最大回文長度為2*8+1=17,那麽原來的最大回文子串長度為17/2=8。

  以上的方法,每次都要以每個字符為中心軸向兩邊擴展,且擴展長隊為1,2,...N/2,則平均時間負責度為O(n^2)。

原理

1)現在如下圖所示,現在已知以idx為中心軸的回文子串的長度為花括號括起來,則現在求以i為中心抽的回文子串長度,首先保證i處於以idx為中心軸的回文串中。那麽i的以idx的對稱點是i‘,且i‘的回文子串的長度也已知(用括號括起),其中i指向c,i‘指向b。(本文的小寫字母都是變量,大寫字母規定為具體字符)

那麽由e為中心的回文子串中得知,b=c。又因為idx的回文不包括a和d,那麽a!=d,否則a=d時,以idx的回文子串還要擴展下去。由因為idx左 到b 和 idx右到c 相等的。有因為a!=d,所以以c為中心軸的回文半徑只有idx右-location(c)。因為若a關於以b為中心的回文的對稱點為a‘。a‘以e為中心軸的回文的對稱點為a‘‘。那麽a=a‘=a‘‘!=b。

技術分享

以下面的例子說明

技術分享

以9號D為中心軸的回文子串的長度為16-2+1=15。他是從2號開始,16號結束。現在也知道以5號B為中心軸的回文子串長度是10-0+1=11。那麽13號B的對稱點就是5號的B。那麽以13號B為中心軸的回文長度是多少?1號D和17號E不相等。現在只要判定以13號B為中心抽的回文子串是否包括17號。若包括17號E,那麽它的對稱點9號。且9號的對稱點是1號D,那麽可知17號應該等於9號等於1號,實際上可知1號和17號不相等。所以以13號為中心抽的回文不包括17號E。有根據以5號和9號為中心的回文串可知 2號--5號 ,8號--5號, 10號--13號 16號--13號 都是相等的。

2)下面是第二種情況,若i‘的回文串的直徑被idx的回文串包含的話。如下圖。

技術分享

已知i關於idx為中心軸的對稱點i‘的最大回文子串如上圖。因為i‘的回文子串不包括a,b則a!=b,有因為a,d和b,c分別關於idx對稱,記b=c,a=d。所以c!=d。又因為在c和d之間是回文,原因在於c和d之間的字符關於idx的a和b之間對稱,且a和b之間是回文串,所以,c和d之間也是回文串。所以i的回文串串的長度和i‘相同。例子如下:

技術分享

3)下面是第三種情況,若i‘的回文左邊界與idx的回文左邊界重合時,如下圖。

技術分享

由idx為中心抽的回文串可知,b=c,a!=d。且i‘的回文長度在a到b之間(不包括a,b)。那麽i的回文串的長度至少如上圖所示。若c=d時,關於i為中心軸的回文還是可以擴展的。若c!=d則剛好是上圖所示的括號內。例子如下。(是c=d的這種情況)

技術分享

i關於idx的對稱點i‘的最長回文子串如上圖,且i‘的回文左邊界與idx重合,所以i為中心的回文需要充陰影邊界開始在往左右兩邊試著擴展。

  4)第四種情況,就是當i沒有被idx為中心的回文包含時,那麽我們沒有任何信息可以利用,只能以i為中心軸,向左右兩邊擴展。找出它的最長回文子串。

技術分享

manacher算法的原理如上所示,代碼將在下章給出。

manacher算法處理最長的回文子串(一)