關於最長迴文串的問題
阿新 • • 發佈:2021-08-20
- 這兩題都屬於區間dp問題
- 他不和最長公共子序列一樣,迴文串需要對比區間內首位字元,所以就決定了他只能從中間向兩邊擴散
- 最後的程式碼會發現:只是狀態轉移的時候賦值問題,子序列不必連續,所以需要去找最大的,而子串連續,只要不相同,這個區間就不是迴文串.
516. 最長迴文子序列
給你一個字串 s ,找出其中最長的迴文子序列,並返回該序列的長度。
子序列定義為:不改變剩餘字元順序的情況下,刪除某些字元或者不刪除任何字元形成的一個序列。
示例 1:
輸入:s = "bbbab"
輸出:4
解釋:一個可能的最長迴文子序列為 "bbbb" 。
解析:兩個字元比較的時候我們需要分別記錄每一個字串的位置,然後去維護dp陣列,直到兩個串遍歷完,
這一題是求一個串的最大回文序列,可以不連續,結果是這個串有,我們化解成子問題就是從最開始的子串長度為一開始,一步一步增加,屬於區間dp,搞清楚轉移方程和初始化後,看一看原始陣列,然後在決定怎麼遍歷.
class Solution { public: //區間dp int longestPalindromeSubseq(string s) { int len = s.size(); vector<vector<int>> dp(len + 1, vector<int>(len + 1, 0)); for(int i = 0; i < len; i++) { dp[i][i] = 1; } for(int i = 1; i < len; i++) { for(int j = i - 1; j >= 0; j--) { if(s[i] == s[j]) { dp[i][j] = dp[i - 1][j + 1] + 2; }else { dp[i][j] = max(dp[i][j + 1], dp[i - 1][j]); } } } return dp[len - 1][0]; } };
5. 最長迴文子串
給你一個字串 s,找到 s 中最長的迴文子串。
示例 1:
輸入:s = "babad"
輸出:"bab"
解釋:"aba" 同樣是符合題意的答案。
class Solution { public: string longestPalindrome(string s) { int len = s.size(); vector<vector<int>> dp(len + 1, vector<int>(len + 1, 0)); for(int i = 0; i < len; i++) { dp[i][i] = 1; } int ans = 0; int start = 0,end = 0; for(int i = 1; i < len; i++) { for(int j = i - 1; j >= 0; j--) { if(s[i] == s[j]) { if(i - j == 1) dp[i][j] = 1; else dp[i][j] = dp[i - 1][j + 1]; } if (dp[i][j] && ans < (i - j + 1)) { ans = (i - j + 1); start = j,end = i; } } } return s.substr(start, end - start + 1); } };