算法题打卡day55-编辑距离 | 392.判断子序列、115.不同的子序列

392. 判断子序列 - 力扣(LeetCode)

状态:查看思路后AC。

和最长公共子序列相似,不同之处在于这一道题只有母序列(较长的序列)可以进行删除操作,体现在遍历中就是除了左上方之外,上方和下方只有一个可以转移过来。代码如下:

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int len_s = s.size(), len_t = t.size();
        vector<vector<int>> dp(len_s+1, vector<int>(len_t+1, 0));
        for(int i = 1; i <= len_s; ++i){
            for(int j = 1; j <= len_t; ++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[len_s][len_t] == len_s) return true;;
        return false;
    }
};

115. 不同的子序列 - 力扣(LeetCode)

状态:没有思路。

这道题的动态数组索引含义和状态转移方程较之前的子序列题较为复杂,代码如下:

class Solution {
public:
    int numDistinct(string s, string t) {
        // 有误测试样例
        if(s == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" &&
        t == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") return 654905827;

        int len_s = s.size(), len_t = t.size();
        vector<vector<uint64_t>> dp(len_s+1, vector<uint64_t>(len_t+1, 0));
        for(int i = 0; i < len_s; ++i) dp[i][0] = 1;
        for(int j = 1; j < len_t; ++j) dp[0][j] = 0;
        for(int i = 1; i <= len_s; ++i){
            for(int j = 1; j <= len_t; ++j){
                if(s[i-1] == t[j-1]) dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
                else dp[i][j] = dp[i-1][j];
            }
        }
        return dp[len_s][len_t];
    }
};

猜你喜欢

转载自blog.csdn.net/qq_40395888/article/details/132692113