翻譯數字串;及最長迴文子串分析
今日面試題:翻譯數字串
翻譯數字串,類似於電話號碼翻譯:給一個數字串,比如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)的情況下完成,需要注意的是,長度為奇數和偶數的中心的情況是不同的。示例程式碼如下:
第四個方法採用字尾陣列,將最長迴文子串的問題轉化為最長公共字首的問題。具體的做法就是:將整個字串翻轉之後,拼接到原字串後,注意用特殊字 符分開,這樣問題就變成了新的字串的某兩個字尾的最長公共字首的問題了。這個方法比較強大,很多字串的問題都能夠巧妙的解決。不過實現起來也相對比較 難,好的實現和差的實現時間複雜度相差很大。大家應該多多練習。
第五個方法叫做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],見下圖。
當 P[j] >= mx - i 的時候,以S[j]為中心的迴文子串不一定完全包含於以S[id]為中心的迴文子串中,但是基於對稱性可知,下圖中兩個綠框所包圍的部分是相同的,也就是 說以S[i]為中心的迴文子串,其向右至少會擴張到mx的位置,也就是說 P[i] >= mx - i。至於mx之後的部分是否對稱,就只能老老實實去匹配了。
對於 mx <= i 的情況,無法對 P[i]做更多的假設,只能P[i] = 1,然後再去匹配了。
理解了上面的一點,就沒有問題了。
【分析完畢】
本文來自微信:待字閨中,2013-09-24釋出,原創@陳利人 ,歡迎大家繼續關注微信公眾賬號“待字閨中”。
相關文章
- Leetcode[字串] 5. 最長迴文子串LeetCode字串
- 演算法之字串——最長迴文子串演算法字串
- java 最長迴文子串Java
- 淺談最長迴文子串求法——字串雜湊字串
- 5. 最長迴文子串
- LeetCode 5.最長迴文子串LeetCode
- 最長迴文子串 -- 三種解答
- 演算法-兩最長迴文子串演算法
- LeetCode-5. 最長迴文子串(Manacher)LeetCode
- 每日一算--最長迴文子串
- [動態規劃] 六、最長迴文子串動態規劃
- 最長迴文子串你學會了嗎?
- LeetCode題集-5 - 最長迴文子串(一)LeetCode
- L2-008 最長對稱子串【最長迴文字串】字串
- leedcode-最長迴文串
- LeetCode - 409 - 最長迴文串LeetCode
- 1203- 最長迴文串
- Leetcode5: Longest Palindromic Substring(最長迴文子串)LeetCode
- 每日一道 LeetCode (48):最長迴文子串LeetCode
- Amazon面試題:尋找最長迴文子串面試題
- 程式碼隨想錄day46 || 647 迴文子串, 516 最長迴文子序列
- 最長子串
- 每天一道演算法題:最長迴文子串演算法
- LeetCode題集-5 - 最長迴文子串之馬拉車(二)LeetCode
- lc1771 由子序列構造的最長迴文串的長度
- JS字串最長迴文查詢JS字串
- 最長上升子串
- 程式碼隨想錄演算法訓練營 | 647. 迴文子串,516.最長迴文子序列演算法
- 判斷迴文串 字串/數字相互轉換字串
- 求字串中不含重複字元的最長子串字串字元
- lCS(最長公共子串)
- LeetCode516. 最長迴文子序列LeetCode
- 程式碼隨想錄演算法訓練營day46| 647. 迴文子串 516.最長迴文子序列演算法
- 最長迴文子序列(不連續) 可輸出迴文序列
- 程式碼隨想錄演算法訓練營第五十七/天 | 516. 最長迴文子序列,647. 迴文子串演算法
- 線性dp:最長公共子串
- 從0打卡leetcode之day 6--最長迴文串LeetCode
- L2-008 最長對稱子串 分數 25
- 線性dp:LeetCode516 .最長迴文子序列LeetCode