代码随想录算法训练营day54|第九章 动态规划part15

目录

392.判断子序列

115.不同的子序列


392.判断子序列

这道题目算是 编辑距离问题 的入门题目(毕竟这里只是涉及到减法),慢慢的,后面就要来解决真正的 编辑距离问题了

代码随想录

这道题和 1143.最长公共子序列本质是相同的,只要判断最长公共子序列的长度恰好等于s字符串的长度即可。除此之外,递推公式也可以精简一下,本来是 if(s[ i ] != t[ j ]) dp[ i + 1 ][ j + 1 ] = max(dp[ i ][ j + 1 ], dp[ i + 1 ][ j ]),但实际上已经确定了s串是长度较小的字符串,i往前挪所得到的最大公共子序列长度一定会变小(而且这道题是外层遍历的s串,所以如果可以最终返回true,i之前的字符一定已经找到对应的了),所以dp[ i ][ j + 1 ]一定小于dp[ i + 1 ][ j ]。

这道题的递推公式还是要分成字符相等和字符不相等。如果字符相等,那就要在原来的基础上加一,如果字符不相等,那就证明当前遍历到的t[j]是没用的,所以就要删除它,删除的方法就是让dp[i+1][j+1]=dp[i+1][j],删除是编辑距离的基本操作之一。

cpp 复制代码
bool isSubsequence(string s, string t) {
        vector<vector<int>> dp(s.size()+1,vector<int>(t.size()+1,0));
        for(int i=0;i<s.size();i++){
            for(int j=0;j<t.size();j++){
                if(s[i]==t[j]) dp[i+1][j+1]=dp[i][j]+1;
                else dp[i+1][j+1]=dp[i+1][j];
            }
        }
        if(dp[s.size()][t.size()]==s.size()) return true;
        else return false;
    }

115.不同的子序列

但相对于刚讲过 392.判断子序列,本题 就有难度了 ,感受一下本题和 392.判断子序列 的区别。

代码随想录

dp[i][j]是以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。这里递推公式还是分成两个部分来推导------

  • s[i] 与 t[j]相等。相等就说明可以利用当前的字符构成目标字符串,于是dp[i+1][j+1]的一部分就是dp[i][j],换言之,这就是遍历到这个字符新增的方法数;但是除了用当前字符构成目标字符串,还可能不用当前的字符就可以构成目标字符串,相当于删除了当前字符所得到的方法数(dp[i+1][j]),换言之这部分就是遍历到这个字符之前累计的方法数。
  • s[i] 与 t[j] 不相等。如果不相等,那就只能删除当前字符得到累计的方法数了。

这道题的遍历顺序自然是从上到下,从左到右,故而必须初始化第一行列。dp[i][0] 表示:以i-1为结尾的s可以随便删除元素,出现空字符串的个数,那么dp[i][0]一定都是1,因为也就是把以i-1为结尾的s,删除所有元素,出现空字符串的个数就是1。再来看dp[0][j],dp[0][j]:空字符串s可以随便删除元素,出现以j-1为结尾的字符串t的个数,那么dp[0][j]一定都是0,s如论如何也变成不了t。最后就要看一个特殊位置了,即:dp[0][0] 应该是多少,dp[0][0]应该是1,空字符串s,可以删除0个元素,变成空字符串t。

最后狗测试点要求必须设置uint64_t这种类型的二维数组,这种比long long储存空间更大,也存储的是整型。

cpp 复制代码
int numDistinct(string s, string t) {
        vector<vector<uint64_t>> dp(t.size()+1,vector<uint64_t>(s.size()+1,0));
        for(int i=0;i<s.size();i++) dp[0][i]=1;
        for(int i=0;i<t.size();i++){
            for(int j=0;j<s.size();j++){
                if(t[i]==s[j]){
                    dp[i+1][j+1]=dp[i][j]+dp[i+1][j];
                }else{
                    dp[i+1][j+1]=dp[i+1][j];
                }
            }
        }
        return dp[t.size()][s.size()];
    }
相关推荐
哎呀呀嗯呀呀15 分钟前
class 031 位运算的骚操作
java·算法·位运算
时清云31 分钟前
【算法】合并两个有序链表
前端·算法·面试
轩辰~1 小时前
磁盘存储链式结构——B树与B+树
数据结构·b树·算法
2401_857297911 小时前
秋招内推2025-招联金融
java·前端·算法·金融·求职招聘
通信仿真实验室1 小时前
MATLAB使用眼图分析QPSK通信系统接收端匹配滤波后的信号
开发语言·算法·matlab
通信仿真实验室2 小时前
(15)衰落信道模型作用于信号是相乘还是卷积
开发语言·人工智能·算法·matlab
Run with the Wind2 小时前
【2024.9.29练习】R 格式
算法
Jeremy_121382 小时前
三种波束形成方法的区别(MVDR、MMSE以及MSNR波束形成器)
算法
远望樱花兔2 小时前
【d59】【Java】【力扣】146.LRU缓存
java·开发语言·算法
秋夜Autumn2 小时前
贪心算法相关知识
算法·贪心算法