dp問題, 最長回文子串
最長回文子串問題指的是在乙個字串中, 是回文子串的長度的最大值. 這裡的回文子串是連續的.
如字串」patzjujztaccbcc」, 他的最長回文子串是」atzjujzta」, 長度為9, 當然它還有其他回文子串如」ccbcc」, 但是長度不夠長.
這類問題似乎有多種解法, 複雜度從o(n^3)到o(n)不等.
下面介紹一種時間複雜度為o(n^2)的.
思路是典型的dp思路, 我們可以考量這樣乙個陣列, dp[i][j], bool型別, 值為1代表字串從s[i]到s[j]是回文子串, 值為0代表不是.
那麼對於任意的i, j, 如何判斷dp[i][j]的值呢? 討論下面兩種情況:
1. s[i] = s[j]時, 如果dp[i+1][j-1] = 0, 即從s[i+1]到s[j-1]是回文子串, 那麼從s[i][j]自然是回文子串, 所以dp[i][j] = dp[i+1][j-1]
2. s[i] != s[j]時, 如論如何dp[i][j] = 0
那麼這樣看思路就非常清晰了, 看上去非常簡單, 按照這個規則判斷一下就好了.
不過其實這道題是非常有技巧的, 我們可以看到要獲取dp[i][j]值, 那麼就需要知道dp[i+1][j-1]的值, 那麼就不能從前往後遍歷i了, 怎麼辦呢? 從後往前遍歷嗎? 當然也不行. 這就是這種方法的精彩所在, 兩套迴圈,外圍遍歷長度, 內圍遍歷字串起始點i.
因為dp[i][j]的長度是j - i + 1, 而dp[i+1][j-1]的長度是j - i - 1, 長度差了兩個, 如果我把長度小的結果都求解出來了, 那麼長度更長的用長度更小的, 無論i是否會更大, 都是可以的. 不得不說很是精彩.
**實現上,注意前面初始化長度 2時對ans賦恰當的值.
#include
using namespace std;
int main()
, ans = 1;
for (int i = 0; i < int(str.size()); ++i)
}for (int len = 3; len <= (int)str.size(); ++len) }}
cout << ans;}/*
patzjujztaccbcc ans = 9
34567536487326483254 ans = 1
*/
最長回文子串DP
給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb 分析 dpdp j i 表示從j到i的子串 若dp j i 為回文串,則dp j 1 i 1 必然回文,...
最長回文子串 dp
給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb 題目位址 回文的主要要求是 字串從中心對稱。例如 aba bb c 假設 對於乙個 字串 a?a 假定...
最長回文子串(區間dp)
輸入乙個字串str,輸出str裡最長回文子串的長度。回文串 指aba abba cccbccc aaaa這種左右對稱的字串。串的子串 乙個串的子串指此 字元 串中連續的一部分字元構成的子 字元 串 例如 abc 這個串的子串 空串 a b c ab bc abc 輸入str str的長度 1000 ...