1. 程式人生 > >Manachar最長迴文子串(o(n))

Manachar最長迴文子串(o(n))

0. 問題定義

最長迴文子串問題:給定一個字串,求它的最長迴文子串長度。

如果一個字串正著讀和反著讀是一樣的,那它就是迴文串。下面是一些迴文串的例項:

12321 a aba abba aaaa tattarrattat(牛津英語詞典中最長的迴文單詞)

1. Brute-force 解法

對於最長迴文子串問題,最簡單粗暴的辦法是:找到字串的所有子串,遍歷每一個子串以驗證它們是否為迴文串。一個子串由子串的起點和終點確定,因此對於一個長度為n的字串,共有n^2個子串。這些子串的平均長度大約是n/2,因此這個解法的時間複雜度是O(n^3)。

2. 改進的方法

顯然所有的迴文串都是對稱的。長度為奇數迴文串以最中間字元的位置為對稱軸左右對稱,而長度為偶數的迴文串的對稱軸在中間兩個字元之間的空隙。可否利用這種對稱性來提高演算法效率呢?答案是肯定的。我們知道整個字串中的所有字元,以及字元間的空隙,都可能是某個迴文子串的對稱軸位置。可以遍歷這些位置,在每個位置上同時向左和向右擴充套件,直到左右兩邊的字元不同,或者達到邊界。對於一個長度為n的字串,這樣的位置一共有n+n-1=2n-1個,在每個位置上平均大約要進行n/4次字元比較,於是此演算法的時間複雜度是O(n^2)。

3. Manacher 演算法

對於一個比較長的字串,O(n^2)的時間複雜度是難以接受的。Can we do better?

先來看看解法2存在的缺陷。

1) 由於迴文串長度的奇偶性造成了不同性質的對稱軸位置,解法2要對兩種情況分別處理;
2) 很多子串被重複多次訪問,造成較差的時間效率。

缺陷2)可以通過這個直觀的小