2020 10 18 動態規劃(最長回文子串)

2021-10-24 22:09:24 字數 2208 閱讀 1303

就在這裡記錄一下動態規劃。

動態規劃的關鍵點就是小問題和大問題的聯絡。用乙個遞迴表,更容易理解。

對於這個題,遞迴函式中,如果i = j,必然是回文,如果i = j-1,只需要比較這兩個位置的值是否一樣,否則,就需要遞迴比較內部的字串。

以abccbd作為例子,最開始是f[0][0](f[i][j]指s.substring(i,j+1)這一子串是否為回文),肯定為true,接著是f01, f11, f02, f12, f22…

i \ j

0a1b

2c3c

4b5d

0atrue

false

false

false

false

false

1btrue

false

false

true

false

2ctrue

true

false

false

3ctrue

false

false

4btrue

false

5dtrue

可以看到,當乙個位置的值為true時,它還需要判斷左斜下方的值是否也為true(如果存在)。比如,f14這裡,先判斷了b == b,接著還要判斷c==c。這就是動態規劃遞迴在**中的體現。

最後在這個過程中會記錄下最長回文出現時的i和j的值。最後根據這個值輸出子串。

然後在leetcode題解裡面學到了乙個表示式:f = (條件a && (條件b || 條件aa)); 即,當滿足條件b時,只需要滿足條件a即可,否則需要滿足條件a的同時也需要滿足進一步的條件aa。

如果是我就會用if(b)else語句來做了。

動態規劃在這裡只是乙個較差的選擇,還有更優的方法。

基本思想是中心擴充套件法:遍歷字串,每遍歷乙個,就以它作為中心,然後擴散出去看是否為回文。這種解法需要先在每乙個字串中間插入乙個字串。abba ——> -a-b-b-a-。

因為題目需要輸出子串,所以需要花一些心思準確定位到原字串合適的位置上。這個不難,畫圖想一想就能寫出**。

這裡是學習了這個部落格的內容,寫的超級詳細,很感謝。這裡用自己的話寫寫自己的理解。

關鍵變數為rl陣列posmaxright

乙個回文串中最左或最右位置的字元與其對稱軸的距離稱為回文半徑,用rl[ ]記錄表示,用rl[i]表示以第i個字元為對稱軸的回文串的回文半徑。

maxright,表示當前訪問到的所有回文子串,所能觸及的最右乙個字元的位置。pos表示maxright對應的回文串的對稱軸所在的位置。

前面一樣先填充字元。首先是一次對整個字串的遍歷,需要將每個位置的回文半徑值rl記錄下來,並且根據其大小,對pos和maxright進行更新。

在這個迴圈裡面,每次迭代首先判斷當前索引的位置在maxright的左邊還是右邊,由此來對rl做乙個初始賦值。

if(k < maxright)

else

當k < maxright時,根據回文的對稱性,此時的rl[k]值是可以參考rl[2*pos-k]的。當然,不能超過maxright的範圍。

在此初始值的基礎上,左右擴充套件,判斷是否有更大的回文子串。

當i=maxright時,就不能借用j的資訊了):

j 	 pos  	 i	maxright

↓ ↓ ↓ ↓

-a-b-c-b-e - e-b-c-b-a -

這個例子中,i對應的j的回文總長度就沒有超過pos的半徑。則不需要繼續判斷新的maxright。

下面這個例子,則超過了pos的半徑,所以需要擴充套件判斷新的maxright。(程式設計為了方便,兩者都進行判斷)

j pos i maxright

↓ ↓ ↓ ↓

-a-b-c-b-a - a-b-c-b-a -???

關鍵點

理解上面三個關鍵變數的含義和作用。

理解如何給rl[k]賦予初始值的。

動態規劃 最長子序列

引出 問題描述 給出乙個序列a1,a2,a3,a4,a5,a6,a7 an,求它的乙個子串行 設為s1,s2,sn 使得這個子串行滿足這樣的性質,s1分析 這題目是經典的dp題目,也可叫作最長上公升子串行或者 最長不下降子串行。有兩種演算法,複雜度分別為o n logn 和o n 2 演算法1 時間...

動態規劃 最長子序列

引出 問題描述 給出乙個序列a1,a2,a3,a4,a5,a6,a7 an,求它的乙個子串行 設為s1,s2,sn 使得這個子串行滿足這樣的性質,s1分析 這題目是經典的dp題目,也可叫作最長上公升子串行或者 最長不下降子串行。有兩種演算法,複雜度分別為o n logn 和o n 2 演算法1 時間...

最長回文串 動態規劃)

半對 給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb 思路一 翻轉字串法。1.將整個字串反轉,然後判斷原始的字串是否在反轉的字串 現。2.只是出現還不...