题解:
考试时也想到拼接字符串,然而就是没想到怎么判断来自两个不同的字符串s1、s2,说到底还是没有彻底理解状态 dp[i][j] 以及状态转移方程。
- 思路:连接 s1 和 s2为 s,将问题转换为[子序列问题][dp]leetcode516:最长回文子序列(medium),然后再加一个判断条件,来判断来自两个不同的字符串s1、s2。
- 关于 dp 方程的求法以及遍历过程,可以看labudadong的讲解子序列问题通用思路|最长回文子序列。
代码如下:
const int N = 2010;
int f[N][N];
class Solution {
public:
// 拼接两个字符串转换为求 最长回文子序列,加了一个判断条件而已
// f[i][j]表示 s[i...j]的最长回文子序列长度,所以我们只需要判断 i 是否在 s1 内部,j 是否在 s2 内部,来保证非空
int longestPalindrome(string& s1, string& s2) {
int n1=s1.size(),n2=s2.size(),res=0;
string s=s1+s2;
int n=s.size();
memset(f,0,sizeof f);
// i 反向遍历,j 从 i 行的 i+1 位置从左到右遍历
for(int i=n-1;i>=0;i--){
f[i][i]=1;
for(int j=i+1;j<n;++j){
if(s[i]==s[j]){
f[i][j]=f[i+1][j-1]+2;
// i 在s1内部,j在s2内部
if(i<n1&&j>=n1)res=max(res,f[i][j]);
}
else f[i][j]=max(f[i+1][j],f[i][j-1]);
}
}
return res;
}
};
一共看了三篇题解 都很棒。谢谢!