描述
给定一个字符串,找到其中最长的回文子序列,并返回该序列的长度。
注:回文序列是指这个序列无论从左读还是从右读都是一样的。
本题中子序列指字符串任意位置删除k(len(s)>=k>=0)个字符后留下的子串。
数据范围:字符串长度满足,
进阶:空间复杂度,时间复杂度。
示例1
输入:"abccsb"
输出:4
说明:最长回文子串是"bccb"
示例2
输入:"abcdewa"
输出:3
说明:最长回文子串是"aba"或"aca"或"ada"或"aea"或"awa"
解决思路:转化为求字符串和其逆序的最长公共子序列的长度
设字符串s的逆字符串为sn,定义二维数组dp,dp[i][j]表示子串s[0:i]和子串sn[0:j]的最长公共子序列的长度。
- 如果s[i]=sn[j],dp[i][j]=dp[i-1][j-1]+1;
- 否则,dp[i][j]=max(dp[i-1][j], dp[i][j-1])。
复杂度分析:时间复杂度,空间复杂度。
实现代码
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string 一个字符串由小写字母构成,长度小于5000
* @return int
*/
int longestPalindromeSubSeq(string s) {
// 转化为求s和s逆序的最长公共子序列
int n = s.length();
vector<vector<int> > dp(n+1, vector<int>(n+1, 0));
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
if(s[i-1] == s[n-j]){
dp[i][j] = dp[i-1][j-1] + 1;
}
else{
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
}
return dp[n][n];
}
};
运行效率