力扣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...