题目如下
给你两个字符串 word1 和 word2 ,请你按下述方法构造一个字符串:
从 word1 中选出某个 非空 子序列 subsequence1 。
从 word2 中选出某个 非空 子序列 subsequence2 。
连接两个子序列 subsequence1 + subsequence2 ,得到字符串。
返回可按上述方法构造的最长 回文串 的 长度 。如果无法构造回文串,返回 0 。
代码如下
- 注意此题与连续字串不同,是一个"子集"
- 直接避免了"排列数"方式的枚举过程,注意到这里的子集仍然是"连续"的
- j < l1 && i >= l1 这个筛选条件至关重要,但是不能放在最前面,因为可能会导致丢失子序列的结果的问题(未初始化的都为0)
class Solution {
public:
int longestPalindrome(string w1, string w2) {
int l1 = w1.size(), l2 = w2.size(), len = l1 + l2;
string w = w1 + w2;
vector<vector<int>> dp(len, vector<int>(len, 0));
int res = (w[l1-1] == w[l1]) ? 2: 0;
for(int i=0;i<len;i++)
for(int j=i;j>=0;j--){
if(i==j){
dp[i][i] = 1;
continue;
}
if(i-j==1){
dp[j][i] = (w[i] == w[j])? 2: 1; //注意这里为数值,不是bool的关系
continue;
}
if(w[i] == w[j]) {
dp[j][i] = dp[j+1][i-1] + 2;
if(j < l1 && i >= l1){
res = max(res, dp[j][i]);
}
}
else //相当于把普通回文字串的这个空缺补上了
dp[j][i] = max(dp[j][i-1], dp[j+1][i]);
}
return res;
}
};