Manachar最長迴文子串(o(n))
阿新 • • 發佈:2019-01-25
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)可以通過這個直觀的小