力扣5 最長回文子串C 詳解

2021-10-04 19:39:04 字數 1433 閱讀 6034

力扣5. 最長回文子串

注:子陣列或者子字串求解問題一般基本是用dp演算法

最長回文子串的解釋:正著讀和反著讀是一樣的。

題目解析:

解法一:動態規劃

從回文子串的定義我們可以得出兩個結論:

(1)如果說乙個子字串是回文子串,那麼給這個子字串兩邊分別加乙個數,如果這2個數相等,那麼這個新的子字串也是回文子串。

(2)回文子串的開始和結束位置的字元一定是相等的。

我們可以用i來表示乙個子字串的起始位置,j來表示乙個子字串的結束位置,用乙個二維陣列來儲存i和j之間的子字串是否是回文子串。看到這可以看出這個問題和揹包問題很像。

根據剛才分析得出的結論我們可知:

dp[i][j] =

dp[i+1][j-1] 

&& 

i和j位置的值是否相等

注:dp[i][j]表示以i開頭,以j結尾的子字串是否是回文子串。

那麼我們從**進入動規入口呢,很明顯我們可以知道:當i和j的位置是同乙個時,也就是單個字元時,肯定是乙個回文子串。

因此我們可以現在表中斜對角的地方都先寫上t(true),然後進行遞推。這裡有乙個問題,我們的遞推順序(也就是掃瞄順序)是怎麼樣子的?

首先我們來下面這種掃瞄方法

很明顯,這種掃瞄方法是錯誤的,因為我們要確定乙個子字串是否是回文子串,我們必須先知道它中間的子字串是否是回文子串【也就是我們必須先知道表中當前位置(i,j)的斜下方位置(i+1,

j-1)的值】。但是現在這種掃瞄方法在要計算

dp[i][j]

的值時,並不知道此時

dp[i+1][j-1]

的值,所以不能這樣掃瞄

正確的掃瞄方法有如下兩種(任選其一進行掃瞄即可):

在判斷子字串是否時回文子串的同時,我們應該設定乙個變數去記錄時回文子串的子字串的長度,並且不斷的用更大的值去更新當前長度。

動態規劃**如下:

注:在寫遞推**時,回文子串長度為2和1時無法用狀態轉移方程得出,因此需做特殊處理。

class

solution 

if( dp[i][j] )   

//更新長度}}

}return

s.substr(start,len);   }};

解法二:中心擴充套件法

待續……

參考:

最長回文子串 力扣5

給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb 利用回文字串的特點 正著讀和反著讀都是一樣的,所以首先把s反轉,利用i和j控制左右邊界,不斷從s中擷取...

力扣 5 最長回文子串

題目 和647類似 給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb 題解 方法一 面試題,要求最長只能一趟迴圈 中心擴散法 class solutio...

力扣 最長回文子串 C

給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。輸入 cbbd 輸出 bb include using namespace std define max a,b a b a b define min...