本文主要是介绍代码随想录训练营Day 60|力扣647. 回文子串、516.最长回文子序列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.回文子串
代码随想录
代码:
class Solution {
public:int countSubstrings(string s) {vector<vector<bool>> dp(s.size(),vector(s.size(),false));int result = 0;for(int i = s.size() - 1; i >= 0; i--){ // 从下往上遍历for(int j = i; j < s.size(); j++){ // 从左往右遍历if(s[i] == s[j]){if(j - i <= 1){dp[i][j] = true;result++;}else if(dp[i + 1][j - 1] == true){dp[i][j] = true;result++;}}}}return result;}
};
思路:
dp数组的含义:dp数组中下标为i到j(包括ij)的连续子串是否是回文子串
dp数组的递推公式:为了方面判断回文子串,并且用上我们之前的推导结果。去想一种可能——如果在一个回文子串两边添加相同的字符,那么新的子串也会是回文子串。因此如果 j - i <= 1的话,说明这个子串只涉及到i和j下标的元素,肯定是回文子串;否则,还要保证里面的子串也是回文子串,即dp[i + 1][j - 1] = true。
dp数组的初始化:只能全部初始化为false
dp数组的遍历顺序:在递推里,已经提到了,我们需要dp[ i + 1][j - 1]的值来推导新值,因此,只能从左到右,从下到上推导。
2.最长回文子序列
代码随想录
代码:
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++){ //因为dp公式里都是长度直接加2,就不要让i和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];}
};
思路:
dp数组的含义:dp数组中下标为i到j的子串中的最长回文子序列的长度为dp[i][j]
dp数组的递推公式:为了方面判断回文子串,并且用上我们之前的推导结果。去想一种可能——如果在一个回文子串两边添加相同的字符,那么新的子串也会是回文子串,即在dp[i + 1][ j - 1]的基础上加2。如果添加的字符不同,就说明这两个字符在回文子串中是互斥的,也就是在dp[i + 1][j]和dp[i][ j - 1]里找最大值。
dp数组的初始化:因为dp公式里都是长度直接加2,没有考虑让i和j相等的情况。所以这个需要我们初始化,i和j相等就是一个字符的子串,肯定是回文子串,长度都为1.
dp数组的遍历顺序:在递推里,已经提到了,我们需要dp[ i + 1][j - 1]的值来推导新值,因此,只能从左到右,从下到上推导。
这篇关于代码随想录训练营Day 60|力扣647. 回文子串、516.最长回文子序列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!