Day57 动规 LC 647 516

75 阅读1分钟

647. 回文子串

心得

没思路

题解

  • 动态规划法

    • 定义dp[i][j] :闭区间[i, j]的子串是否为回文串

    • 递推:

      • 考虑三种情况,i j等的单字符情况 i j相差1的连续情况(由此也可引入双指针法,对称取决内部1个或者2个元素为中心)
      • 情况三,在当前左右对称情况下,判断里面即可即取决于dp[i+1][j-1]
    • 遍历顺序:参考遍历顺序,需要先下后上,先左后右

    • 初始化:默认都false

  • 双指针法:

    • 考虑由中心元素,两边拓展而成,中心元素可单可双
// 动规 O(n^2) O(n^2)
class Solution {
public:
    int countSubstrings(string s) {
        // dp[i][j] 表示闭区间[i,j]的子串是否为回文子串
        vector<vector<bool>> dp(s.size(), vector<bool>(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]) && (j - i <= 1 || dp[i + 1][j - 1])) {
                    result++;
                    dp[i][j] = true;
                }
            }
        }
        return result;
    }
};
// 双指针 O(n^2) O(1)
class Solution {
public:
    int countSubstrings(string s) {
        int result = 0;
        for (int i = 0; i < s.size(); i++) {
            result += extend(s, i, i, s.size());
            result += extend(s, i, i + 1, s.size());
        }
        return result;
    }

    int extend(const string& s, int i, int j, int n) {
        int res = 0;
        while ( i >= 0 && j < n && s[i] == s[j]) {
            i--;
            j++;
            res++;
        }
        return res;
    }
};

516. 最长回文子序列

心得

  • 注意回文子序列和回文子串区别,子串是连续的,子序列是非连续的

题解

  • 此时可以dp[i][j]直接表示最长长度,还是考虑区间[i, j] ,考虑相等不等对于长度的叠加,注意遍历顺序由递推推出遍历顺序,同时初始化值
class Solution {
public:
    int longestPalindromeSubseq(string s) {
        // dp[i][j]闭区间[i, j]的最长回文子序列
        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++) { // 为了保证j - 1有意义
                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];
    }
};