首先需要清楚子串和子序列的区别:
子串就是得到的子字符串中的字符和原本的字符串中该字符的位置一样;
比如bbbab最长的回文子串就是bbb或者bab
子序列就是不需要完全符合原本字符串中字符的位置,只要是按照原本字符串中字符的顺序就可以
比如bbbab的最长子序列就是bbbb
(自己理解)
最长回文子序列:
给定一个字符串s,找到其中最长的回文子序列。可以假设s的最大长度为1000。
class Solution {
public:
int longestPalindromeSubseq(string s) {
if(s.size() == 0 || s.size() == 1) return s.size();
int dp[s.size()][s.size()];
memset(dp,0,sizeof(dp));
for(int i=0;i<s.size();++i)
{
dp[i][i]=1;
for(int j=i-1;j>=0;--j)
{
if(s[i] == s[j])
{
dp[i][j] = 2+dp[i-1][j+1];
}
else
{
dp[i][j] = max(dp[i][j+1],dp[i-1][j]);
}
}
}
return dp[s.size()-1][0];
}
};
最长回文子串:
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
class Solution {
public:
bool ispa(string t)
{
int ss=0,ee=t.size()-1;
while(ss < ee)
{
if(t[ss]!=t[ee])
{
return false;
}
ss++;
ee--;
}
return true;
}
string longestPalindrome(string s) {
string res="";
// for(int i=0;i<s.size();++i) 只能通过一半左右
// {
// for(int j=i;j<s.size();++j)
// {
// string t = s.substr(i,j-i+1);
// if(ispa(t) && j-i+1>res.size())
// {
// res=t;
// }
// }
// }
int dp[s.size()+1][s.size()+1];
memset(dp,0,sizeof(dp));
for(int i=0;i<s.size();++i)
{
for(int j=0;j<=i;++j)
{
if(s[i] == s[j] && (i-j<=2 || dp[i-1][j+1]))
{
dp[i][j]=1;
}
if(dp[i][j] && i-j+1>res.size())
{
res = s.substr(j,i-j+1);
}
}
}
return res;
}
};