Day55 动规 LC 392 115

99 阅读1分钟

392. 判断子序列

心得

题解

  • dp[i][j]表示以i-1结尾的字符串和j-1结尾的字符串序列的相同的子序列长度,结果条件就是最长公共是不是等于短的
  • 时间O(n * m) 空间(n * m)
class Solution {
public:
    bool isSubsequence(string s, string t) {
        vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1, 0));
        for (int i = 1; i <= s.size(); i++) {
            for (int j = 1; j <= t.size(); j++){
                if (s[i - 1] == t[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                }else dp[i][j] = dp[i][j - 1];
            }
        }
        if (dp[s.size()][t.size()] == s.size()) return true;
        return false;
    }
};

115. 不同的子序列

心得

题解

  • dp[i][j] 表示以i-1结尾的字符串中出现以j-1结尾的子序列的个数即大的中通过删除方式,出现小的串的个数
  • 递推公式在s[i -1] == s[j - 1]时,由于求的是匹配的次数,并非匹配就一定要在i-1处,也可能在此之前,所以在该位置相等时,包含两种情况:匹配该位置对应dp[i - 1][j - 1]或者不匹配改位置即dp[i - 1][j - 1]
  • 初始化按照含义即可
class Solution {
public:
    int numDistinct(string s, string t) {
        vector<vector<uint64_t>> dp(s.size() + 1, vector<uint64_t>(t.size() + 1, 0));
        for (int i = 0; i <= s.size(); i++) dp[i][0] = 1;
        for (int j = 1; j <= t.size(); j++) dp[0][j] = 0;
        for (int i = 1; i <= s.size(); i++) {
            for (int j = 1; j <= t.size(); j++){
                if (s[i - 1] == t[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j - 1];
                } else {
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        return dp[s.size()][t.size()];
    }
};