关于最长回文串的问题
- 这两题都属于区间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);
}
};

浙公网安备 33010602011771号