647. 回文子串
这道题看了Carl的题解明白了。本题一大重点是确定遍历顺序:因为我们是一步步 从小到大来i到j之间是不是回文串,所以我们就不能从小到大 从左到右来遍历了。需要i从最大值,然后j从最小值,从左往右遍历。然后必须确保j要小于等于i才行。这个我学的不是很扎实,还需要再做一遍。
class Solution {
public:
int countSubstrings(string s) {
int s_length = s.length();
int result = 0;
vector<vector<bool>> dp(s.length(),vector<bool>(s.length(),false));
for(int i=s_length-1; i>=0; i--){
for(int j=i; j<s_length; j++){
if(s[i] == s[j]){
if(j-i <= 1){
dp[i][j] = true;
result++;
}
else if(dp[i+1][j-1]){
dp[i][j] = true;
result++;
}
}
}
}
return result;
}
};
516.最长回文子序列
真的是太聪明了。我一直没想明白如果目前的i到j之间的字符串本身如果不是整体的回文,其实就应该取dp[i + 1][j]和dp[i][j - 1]中最大的。这就是从小的数组到大的一步步推出来最大的回文子序列长度。
这道题我没自己写,但是明天应该自己写一遍。
class Solution {
public:
int longestPalindromeSubseq(string s) {
vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));
for (int i = 0; i < s.size(); i++) dp[i][i] = 1;
for (int i = s.size() - 1; i >= 0; i--) {
for (int j = i + 1; j < s.size(); j++) {
if (s[i] == s[j]) {
dp[i][j] = dp[i + 1][j - 1] + 2;
} else {
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
}
}
}
return dp[0][s.size() - 1];
}
};