1.回文子串 题647
①dp数组含义
判断回文子串可以用头元素和尾元素是否相等的方式,设dp[i] [j]为[i,j]子串是否为回文子串,是则为true,否为false。
②递推公式
若 s[i] == s[j] ,分三种情况:i == j,即只有一个元素,那么只有一个回文子串,结果为true;
j - i =1,比如aa,那么也是回文子串,结果为true;
j - i >=1, 就得看dp[i+1] [j-1]的结果,结果与dp[i+1] [j-1]相同。
③初始化
全部默认为false。
④遍历顺序
看递推方向,从下往上,从左到右。
class Solution {
public:int countSubstrings(string s) {vector> 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++) { //j必须大于等于iif (s[i] == s[j]) {if (j - i <= 1) { // 情况一 和 情况二result++;dp[i][j] = true;} else if (dp[i + 1][j - 1]) { // 情况三result++;dp[i][j] = true;}}}}return result;}
};
2.最长回文子序列 题516
首先是子序列,然后才是回文,而子序列不一定是连续的。
①dp数组含义
跟回文子串差不多。[i] , j]的范围的回文子序列的长度。
②递推公式。
分两种情况,若s[i] == s[j],那么dp[i] [j] = dp[i+1] [j-1] + 2
若s[i] != s[j], 那么也有两种情况,由于回文子序列可以不连续,只取s[i] 或者 s[j] 也有可能构成回文子序列。故只取s[i] 为 dp[i] [j-1],只取s[j] 为dp[i+1] [j],取这两种情况的最大值。
③初始化
根据递推公式,i不断+1,j不断-1,不断向中间靠拢,直到i = j,而这里就是需要初始化的地方,i = j为一个元素,一个元素也为回文子序列,所以赋值1。
④遍历顺序
class Solution {
public:int longestPalindromeSubseq(string s) {vector> dp(s.size(), vector(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];}
};
上一篇:【精华】搞定JVM调优学习
下一篇:yolov8训练自己的数据集