翻譯數字串;及最長迴文子串分析

紫鳳發表於2013-10-16

今日面試題:翻譯數字串

翻譯數字串,類似於電話號碼翻譯:給一個數字串,比如12259,對映到字母陣列,比如,1 -> a, 2-> b,... , 12 -> l ,... 26-> z。那麼,12259 -> lyi 或 abbei 或 lbei 或 abyi。輸入一個數字串,判斷是否能轉換成字串,如果能,則列印所以有可能的轉換成的字串。動手寫寫吧。

==========================================================

最長迴文子串分析

原題

給定字串,找到它的最長迴文子串,都有哪些思路呢?例如"adaiziguizhongrenenrgnohziugiziadb",迴文字串很多了,但最長的是"daiziguizhongrenenrgnohziugiziad"。

分析

這是一個十分經典的題目,方法也很多。下面我們在介紹的時候,不會每個方法都很詳細的介紹,不過同學們在練習的時候需要每個方法都寫一下,進而才能夠舉一反三。

第一個方法當然是暴力法,外面的兩層迴圈找到所有子串,第三層迴圈判斷子串是否是迴文。方法的時間複雜度為O(n^3),空間複雜度為O(1)。

第二個方法,大家是否記得上期的題目中,是如何判斷子串是迴文的麼?採用的是動態規劃的方法。開闢一個P[i][j]用來表示str[i..j]是否為迴文,P[i][j]的狀態轉移方程如下:

1. 當i==j時,P[i][j]=true

2. 當i+1==j時,P[i][j]=str[i]==str[j]

3. 其他,P[i][j]=P[i+1][j-1]&&(str[i]==str[j])

這樣,這個方法的時間複雜度為O(n^2),空間複雜度為O(n^2)。比暴力法有很大的改進。

第三個方法,可以從上面那個方法的狀態轉移方程獲得啟發,對於每一個迴文子串可以先確定一箇中心,然後向兩邊擴充套件,這樣可以在時間複雜度O(n^2),空間複雜度O(1)的情況下完成,需要注意的是,長度為奇數和偶數的中心的情況是不同的。示例程式碼如下:

enter image description here

第四個方法採用字尾陣列,將最長迴文子串的問題轉化為最長公共字首的問題。具體的做法就是:將整個字串翻轉之後,拼接到原字串後,注意用特殊字 符分開,這樣問題就變成了新的字串的某兩個字尾的最長公共字首的問題了。這個方法比較強大,很多字串的問題都能夠巧妙的解決。不過實現起來也相對比較 難,好的實現和差的實現時間複雜度相差很大。大家應該多多練習。

第五個方法叫做Manacher演算法,是一種線性時間的方法,非常巧妙。首先,我們在上面的方法中個,都要考慮迴文長度為奇數或者偶數的情況。這個 方法,引入一個技巧,使得奇數和偶數的情況統一處理了。具體做法如下:abba轉換為#a#b#b#a#,也就是在每一個字元兩邊都加上一個特殊字元。

然後建立一個新的P[i]表示,以第i個字元為中心的迴文字串的半徑。例如上面的例子,對應的P如下,設S為原始字串:

S#a#b#b#a#

P121252121

通過觀察上面的表,大家可以發現P[i]-1就是實際迴文字串的長度。如果知道P,遍歷一次就知道最長的迴文子串。可以該如何計算P呢?這是這個演算法最核心的部分。

下面的討論基本轉自部落格:http://www.felix021.com/blog/read.php?2040 部落格中對Manacher演算法介紹得也非常好,向大家推薦。

演算法引入兩個變數id和mx,id表示最長迴文子串的中心位置,mx表示最長迴文字串的邊界位置,即:mx=id+P[id]。

在這裡有一個非常有用而且神奇的結論:如果mx > i,那麼P[i] >= MIN(P[2 * id - i], mx - i) 分開理解就是:

1. 如果mx - i > P[j], 則P[i]=P[j]

2. 否則,P[i]  = mx - i.

這兩個該如何理解呢?具體的解釋請看下面的兩個圖。

當 mx - i > P[j] 的時候,以S[j]為中心的迴文子串包含在以S[id]為中心的迴文子串中,由於 i 和 j 對稱,以S[i]為中心的迴文子串必然包含在以S[id]為中心的迴文子串中,所以必有 P[i] = P[j],見下圖。

enter image description here

當 P[j] >= mx - i 的時候,以S[j]為中心的迴文子串不一定完全包含於以S[id]為中心的迴文子串中,但是基於對稱性可知,下圖中兩個綠框所包圍的部分是相同的,也就是 說以S[i]為中心的迴文子串,其向右至少會擴張到mx的位置,也就是說 P[i] >= mx - i。至於mx之後的部分是否對稱,就只能老老實實去匹配了。

enter image description here

對於 mx <= i 的情況,無法對 P[i]做更多的假設,只能P[i] = 1,然後再去匹配了。

理解了上面的一點,就沒有問題了。

【分析完畢】

本文來自微信:待字閨中,2013-09-24釋出,原創@陳利人 ,歡迎大家繼續關注微信公眾賬號“待字閨中”。

相關文章