最長回文子串(動態規劃和遞迴)

2021-07-10 23:02:03 字數 2481 閱讀 5159

給乙個字串,找出它的最長的回文子串行的長度。例如,如果給定的序列是「bbabcbcab」,則輸出應該是7,「babcbab」是在它的最長回文子串行。 「bbbbb」和「bbcbb」也都是該字串的回文子串行,但不是最長的。注意和最長回文子串的區別(參考:最長回文串)!這裡說的子串行,類似最長公共子串行lcs( longest common subsequence)問題,可以是不連續的。這就是lps(longest palindromic subsequence)問題。

最直接的解決方法是:生成給定字串的所有子串行,並找出最長的回文序列,這個方法的複雜度是指數級的。下面來分析怎麼用動態規劃解決。

假設 x[0 ... n-1]  是給定的序列,長度為n.  讓 l(0,n-1) 表示 序列 x[0 ... n-1] 的最長回文子串行的長度。

1. 如果x的最後乙個元素和第乙個元素是相同的,這時:l(0, n-1) = l(1, n-2) + 2 ,  還以 「bbabcbcab」 為例,第乙個和最後乙個相同,因此 l(1,n-2) 就表示藍色的部分。

2. 如果不相同:l(0, n-1) = max ( l(1, n-1) ,  l(0, n-2) )。 以」babcbca」 為例,l(1,n-1)即為去掉第乙個元素的子串行,l(0, n-2)為去掉最後乙個元素。

有了上面的公式,可以很容易的寫出下面的遞迴程式:

01#include

02#include

03intlps(char*seq,inti,intj)

04

17

18/* 測試 */

19intmain()

20

output: the lnegth of the lps is 5 (即為: amama)

畫出上面程式的遞迴樹(部分),已乙個長度為6 的字串為例:

1l(0, 5)

2/        \

3/          \

4l(1,5)          l(0,4)

5/    \            /    \

6/      \          /      \

7l(2,5)    l(1,4)  l(1,4)  l(0,3)

可見有許多重複的計算,例如l(1,4)。該問題符合動態規劃的兩個主要性質:重疊子問題

最優子結構

。下面通過動態規劃的方法解決,通過自下而上的方式打表,儲存子問題的最優解。

01intlpsdp(char* str,intn)else

16dp[j][j+i] = tmp;

17}

18}

19//返回串 str[0][n-1] 的結果

20returndp[0][n-1];

21}

該演算法的時間複雜度為o(n^2)。其實這個問題和 最長公共子串行 問題有些相似之處,我們可以對lcs演算法做些修改,來解決此問題:

1) 對給定的字串逆序 儲存在另乙個陣列 rev 中

2) 再求這兩個 字串的 lcs的長度

時間複雜度也為 o(n^2)。

參考:

動態規劃 最長回文子串

動態規劃 最長回文子串 題目描述 給出乙個字串s,求s的最長回文子串的長度 樣例 字串 patzjujztaccbcc 的最長回文子串為 atzjujzta 長度為9。動態規劃思想 令dp i j 表示s i 至s j 所表示的子串是否是回文子串,是則為1,不是為0。這樣根據s i 是否等於s j ...

動態規劃 最長回文子串

給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb 本題有很多種解法,最簡單的暴力求解,但是會超時。下面分別說明動態規劃法和中心擴散法。解法一 動態規劃法...

最長回文子串 動態規劃

給出乙個字串s,求s的最長回文子串的長度。樣例輸入 patzjujztaccbcc 輸出 9 尋找二維動態規劃表示式dp i j 如果直接用dp i j 表示子符串從s i 到s j 的最長回文子串長度無法得出遞推表示式。令dp i j 表示s i 至s j 所表示的子串是否是回文子串,是則為1,不...