今日面試題:最長迴文子串;及迴文分割分析

紫鳳發表於2013-09-26

今日面試題:最長迴文子串

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

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

迴文分割

分析

原題對一個字串按照迴文進行分割,例如aba|b|bbabb|a|b|aba就是字串ababbbabbababa的一個迴文分割,每一個字串都是一個迴文。請找到可以分割的最少的字串數。例如:

1. ababbbabbababa最少4個字串,分割三次:a|babbbab|b|ababa

2. 如果字串整體是迴文,則需要0次分割,最少1個字串

分析

這個題目很多做過leetcode的同學都見過,所以很多同學直接回復了DP。不過還是建議大家動手寫一寫。熟能生巧的。那麼該如何分析這個題目呢?

我們可以先不理會最少分割,從對字串進行迴文分割入手,對於迴文字串的判斷是不可避免的。我們可以從字串的第一個字元開始,找滿足迴文的字 串。假設str[0..k]是一個迴文字串(包括0和k),問題可以分解為子問題了:假設count[i]表示從i開始、包括i的字串的迴文切割數(當 然是有很多可能的),如果str[0..k]是一個迴文字串,則count[i]=count[k+1] + 1。找到遞迴表示式,這裡要注意,從0開始,可能會有多個迴文子串,也正是因為如此,才有最少分割一說。

上面的演算法中,每次要遍歷一遍字串,同時要判斷子串是否是迴文,這裡顯然是存在重複計算的。這給我們改進提供了可能。那麼該如何更好的判斷迴文呢?我們設定P[i][j]:

1. 為true時,表示str[i..j]為迴文

2. 為false時,表示str[i..j]不是迴文

則,當:

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

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

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

這個P該如何構建呢?根據其狀態轉移的方程,P[i][j]所代表的字串,長度從1開始變化,逐漸到整個字串,是這樣的一個構建的過程,所以外層迴圈應該是所要判斷的字串的長度。基本程式碼如下:

enter image description here

迴文字串判斷完畢之後,改如何計算最少分割呢?我們可以根據P構建一棵樹,然後寬度有限遍歷,找到樹的最小深度。上面判斷迴文的時間複雜度為 O(n^2),構建樹的時間複雜度為遍歷一次P,時間複雜度也是O(n^2),最後樹的遍歷,時間複雜度要小於O(n^2),這樣,整體的時間複雜度為 O(n^2)。

也可以不這樣考慮,如同我們上面說的,我們用C[i]表示str[0..j]的最小分割數,然後變數k從1開始到n遍歷,找到最少的分割。時間複雜度O(n^2)。

【分析完畢】

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

相關文章