Day55【动态规划】392.判断子序列、115.不同的子序列

news2024/12/27 11:48:30

392.判断子序列

力扣题目链接/文章讲解

视频讲解

本题目可以用双指针法来做

class Solution {
public:
    bool isSubsequence(string s, string t) {
        // pointer to s, pointer to t
        int ps = 0, pt = 0; 
        for (pt = 0; pt < t.size(); ++pt) { // 遍历t,在t中按顺序寻找子序列s
            if (s[ps] == t[pt])
                ps++;
        }
        return ps == s.size();
    }
};

也可以用动态规划!掌握本题的动态规划解法是对后面要讲解的编辑距离的题目打下基础 

动态规划五部曲!

1、确定 dp 数组下标及值含义

dp[i][j]:i 和 j 表示以下标 i 为结尾的字符串 s,和以下标 j 为结尾的字符串 t,值表示这两个字符串最长相同子序列的长度为 dp[i][j] 

2、确定递推公式

if (s[i] == t[j]),那么 dp[i][j] = dp[i - 1][j - 1] + 1,因为找到了一个相同的字符,相同子序列长度自然要在 dp[i - 1][j - 1] 的基础上加 1(如果不理解,回看一下 dp[i][j] 的定义) 

if (s[i] != t[j]),那么 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]),即 s[0, i] 与 t[0, j] 的最长相同子序列长度一定是 s[0, i - 1] 与 t[0, j] 的最长公共子序列长度s[0, i] 与 t[0, j - 1] 的最长公共子序列长度之一,取最大的

3、dp 数组初始化

需要初始化第一行和第一列

dp[0][j] 表示 s[0] 与 t[0, j] 的最长公共子序列长度

dp[i][0] 表示 s[0, i] 与 t[0] 的最长公共子序列长度 

4、确定遍历顺序 

从递推公式可以看出 dp[i][j] 都是依赖于 dp[i - 1][j - 1] 和 dp[i][j - 1],那么遍历顺序应该是从上到下,从左到右

5、打印 dp 数组验证

最后的结果应该是看两个字符串最长相同子序列的长度是否和 s 的长度相同

代码如下

class Solution {
public:
    bool isSubsequence(string s, string t) {

        if (s.size() == 0) return true;
        if (t.size() == 0) return false;

        vector<vector<int> > dp(s.size(), vector<int>(t.size(), 1));

        for (int i = 0; i < s.size(); ++i) {
            if (s[i] == t[0])
                break;
            dp[i][0] = 0;
        }

        for (int j = 0; j < t.size(); ++j) {
            if (s[0] == t[j])
                break;
            dp[0][j] = 0;
        }

        for (int i = 1; i < s.size(); ++i) {
            for (int j = 1; j < t.size(); ++j) {
                if (s[i] == t[j])
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                else
                    dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);
            }
        }
        
        return dp[s.size() - 1][t.size() - 1] == s.size();
    }
};

115.不同的子序列

力扣题目链接/文章 讲解

视频讲解

1、定义 dp 数组下标及值的含义

我们通过之前的题目已经可以感觉到,对于比较两个数组,需要定义二维的 dp 才能把两个数组中每个元素的比较情况展现出来 

dp[i][j]:以下标 i 结尾的 s 含有以下标 j 结尾的 t 的个数

2、确定递推公式 

考虑串 s[0, i] 有多少种方式含有 t[0, j]

首先,如果 s[i] != t[j]

那么 s[0, i] 有含有 t[0, j] 的方式数,与 s[0, i - 1] 含有 t[0, j] 的方式数相等,即 dp[i][j] = dp[i - 1][j]

如果 s[i] == t[j]

那么 s[0, i] 有含有 t[0, j] 的有两种情况

  • s[0, i - 1] 已经含有 t[0, j] 了

这种情况的方式数量为 dp[i - 1][j]

  • s[0, i - 1] 含有 t[0, j - 1],即 s[i] 与 t[j] 匹配

这种情况的方式数量为 dp[i - 1][j - 1] 

需要对这两种 s[i] == t[j] 下的情况求和 

if (s[i] != t[j])
    dp[i][j] = dp[i - 1][j];
else if (s[i] == t[j])
    dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1];

3、dp 数组初始化

初始化第一列和第一行

第一列:dp[i][0],即以下标 i 结尾的 s 含有 t[0] 的个数

第一行:dp[0][j],即 s[0] 含有 t[0, j] 的个数,当 j 大于 0 时一定为 0,dp[0][0] 为 0 或 1

4、确定遍历顺序

根据递推公式,从上往下从左往右遍历填充 dp 数组

5、打印 dp 数组验证

class Solution {
public:
    int numDistinct(string s, string t) {

        if (s.size() == 0) return 0;

        vector<vector<uint64_t> > dp(s.size(), vector<uint64_t>(t.size(), 0));

        int num = 0;
        for (int i = 0; i < s.size(); ++i) {    // dp[i][0]
            if (s[i] == t[0])
                ++num;
            dp[i][0] = num;
        }
        
        // dp[0][j]
        if (t[0] == s[0])
            dp[0][0] = 1; 


        for (int i = 1; i < s.size(); ++i) {
            for (int j = 1; j < t.size(); ++j) {
                if (s[i] != t[j])
                    dp[i][j] = dp[i - 1][j];
                else if (s[i] == t[j])
                    dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1];
            }
        }

        return dp[s.size() - 1][t.size() - 1];
    }
};

回顾总结 

对于比较两个数组,需要定义二维的 dp 才能把两个数组中每个元素的比较情况展现出来 

这一类问题,基本是要分析两种情况

  • s[i] 与 t[j]相等
  • s[i] 与 t[j] 不相等

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/583167.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kali-linux Gerix Wifi Cracker破解无线网络

Gerix Wifi Cracker是另一个aircrack图形用户界面的无线网络破解工具。本节将介绍使用该工具破解无线网络及创建假的接入点。 9.3.1 Gerix破解WEP加密的无线网络 在前面介绍了手动使用Aircrack-ng破解WEP和WPA/WPA2加密的无线网络。为了方便&#xff0c;本小节将介绍使用Geri…

数字图像处理①基于ADMM的全变分去噪算法

文章目录 1. Problem2. 仿真结果3. MATLAB算法4. 源码地址参考文献 1. Problem 在图像处理中&#xff0c;图像信号总会因为各种原因受到噪声的干扰&#xff0c;其中高斯噪声就是典型的干扰类型之一。 针对图像去噪的模型有很多种&#xff0c;其中全变分模型被认为是最有效的模…

北醒Modbus协议在Python下实现功能配置

目录 实验目的测试环境Python库需求Benewake(北醒) TF雷达接口及通讯协议说明接口定义Modbus通信协议说明功能码说明 接线示意图库安装说明例程运行与测试 实验目的 实现485接口系列雷达Modbus协议在Python上实现功能配置。 本例程界面分为主菜单、测距子菜单、配置子菜单&…

社区团购-v.1.6.0更新

likeshop社区团购系统发布新版本1.6.0&#xff0c;主要更新如下&#xff1a; 新增&#xff1a; 小程序-登录引导用户填写头像和昵称 小程序-热更新代码弹窗 后台-正版检测、版本检测 后台-页面装修支持拖拽排序 后台-订单管理增加导出功能 修复&#xff1a; 后台-关联团…

本地化部署AI语言模型RWKV指南,ChatGPT顿时感觉不香了。

之前由于ChatGpt处处受限&#xff0c;又没法注册的同学们有福了&#xff0c;我们可以在自己电脑上本地化部署一套AI语言模型&#xff0c;且对于电脑配置要求也不是非常高&#xff0c;对它就是RWKV。 关于RWKV RWKV是一个开源且允许商用的大语言模型&#xff0c;灵活性很高且极…

Linux之搭建环境

文章目录 1 FileZilla软件2 Linux搭建samba文件共享服务器&#xff0c;实现基于Linux和Windows的共享文件服务2.1 smaba的安装与基本应用2.2 samba的账号权限配置 1 FileZilla软件 在跟着正点原子教程安装后&#xff0c;出现如下问题 解决方法如下 参考文章解决FileZilla连接…

游戏配音怎么弄的?分享三个游戏配音制作方法

随着时代的发展&#xff0c;人们对于配音的要求也越来越高&#xff0c;除了传统的文字配音外&#xff0c;现在又出现了游戏配音。其实游戏配音也是有一定门槛的&#xff0c;并不是人人都可以做得好的。但是如果你想要拥有一位自己喜欢的游戏角色&#xff0c;那么你就要学会游戏…

MyBatis 快速入门(上)

文章目录 一. MyBatis 是什么?二. 学习 MyBatis 的意义三. MyBatis 学习四. 创建 Mybatis 查询4.1 创建数据库和表4. 2 MyBatis 环境搭建1. 添加 MyBatis 框架支持image-202305052040340772. 设置 MyBatis 的配置信息2.1 设置数据库连接的相关信息2.2 MyBatis 的xml 保存路径 …

如何白嫖可联网GPT- NEW Bing

这里写自定义目录标题 前沿方法安装总结 前沿 目前我们想体验可联网的GPT只能去OPENAI官网购买plus会员&#xff0c;一个月20刀&#xff0c;换算一下的话大概在140左右&#xff0c;当然由于OPENAI某些原因经常封禁不符合规定的账号&#xff0c;那么有没有一种办法能白嫖快速的…

Qt Qml 实现键鼠长时间未操作锁屏

文章目录 摘要实现思路键盘鼠标监控百度到的方法我的自己方法 最后 关键字&#xff1a; Qt、 Qml、 QInputEvent 、 QStandardItem、 eventFilter 摘要 今日需求&#xff1a; 项目中需要实时检测用户是否长时间为操作键盘和鼠标&#xff0c;如果超过预设时间未操作键盘和…

Linux之管道

目录 Linux之管道 操作符号 作用 用法 管道符使用场合 匿名管道与命名管道的区别 如何创建命名管道 案例举例 案例1 --- 将/etc/passwd中的用户按UID大小排序 案例2 --- 统计出最占CPU的5个进程 案例3 --- 统计当前/etc/passwd中用户使用的shell类型 案例4 --- 统计网站…

Java大数据文件处理方法

前言 Java大数据文件处理是一种使用Java编写的大型数据处理技术&#xff0c;特别适用于处理大型数据文件。在这篇文章中&#xff0c;我们将了解什么是Java大数据文件处理&#xff0c;为什么它很重要以及Java大数据文件处理的方法和技术。 一、什么是Java大数据文件处理&#…

交易信号有效性测算1——N日涨跌幅

在交易信号发出后&#xff0c;我们需要一些程序化的流程&#xff0c;来验证信号的有效性&#xff0c;其中信号发出后N日的涨跌幅就是一个比较常见的任务 布林带交易策略 我们以布林带&#xff08;BOLL&#xff09;交易策略为示例&#xff1a; 中轨线 N日移动平均线上轨线 …

Linux 上的 .NET 崩溃了怎么抓 Dump

一&#xff1a;背景 1. 讲故事 训练营中有朋友问在 Linux 上如何抓 crash dump&#xff0c;在我的系列文章中演示的大多是在 Windows 平台上&#xff0c;这也没办法要跟着市场走&#xff0c;谁让 .NET 的主战场在工控 和 医疗 呢&#xff0c;上一张在 合肥 分享时的一个统计图…

Unity3D:项目 ID 不匹配的情况下如何应对

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 3D工具集&#xff1a; NSDT简石数字孪生 如果在 Services 窗口的 Settings 中找不到项目 ID&#xff0c;或者如果发现项目 ID 不匹配&#xff0c;这可能是因为使用了较早版本的 Unity 来升级项目&#xff0c;或在脱机时创建…

Win10电脑应用程序并行配置不正确怎么办?

Win10电脑应用程序并行配置不正确怎么办&#xff1f;有用户在运行某些软件时&#xff0c;突然提示出错信息“应用程序无法启动&#xff0c;因为应用程序的并行配置不正确&#xff0c;出现这一问题可能是禁用本地相关服务&#xff0c;或者新安装的系统缺少必要的VC 运行。那么具…

PTQ-PDPMV1 PROSOFT DP主网络接口模块

Quantum的PROFIBUS DP主网络接口模块 PTQ-PDPMV1 PROFIBUS DP主网络接口允许Quantum处理器与支持PROFIBUS DP V0或V1的从设备轻松连接。该模块作为PROFIBUS网络和处理器之间的输入/输出模块。PROFIBUS是工业自动化中最常用的协议之一。应用领域包括电力和配电、石化、水和天然…

基于stm32mp157 linux开发板ARM裸机开发教程7:Cortex-A7 GPIO 实验(连载中)

前言&#xff1a; 目前针对ARM Cortex-A7裸机开发文档及视频进行了二次升级持续更新中&#xff0c;使其内容更加丰富&#xff0c;讲解更加细致&#xff0c;全文所使用的开发平台均为华清远见FS-MP1A开发板&#xff08;STM32MP157开发板&#xff09; 针对对FS-MP1A开发板&…

如何在命令行编译运行java程序?

2023年5月29日&#xff0c;周一下午&#xff1a; 好久没写java程序了&#xff0c;今天居然忘了怎么用命令行编译运行java程序了&#xff0c;还好后来想起来了&#xff0c;为了避免忘记&#xff0c;写篇博客记录一下 1、先用记事本等编辑器写一个java程序&#xff0c;文件名要和…

网络货运系统源码 网络货运平台源码,货运APP源码 货物运输管理源码

网络货运系统源码 网络货运平台源码&#xff0c;货运APP源码 货物运输管理源码 网络货运为无车承运人更名而来&#xff0c;网络货运平台的好处可以节省找车找货的时间与成本。根据国家对智慧物流行业的发展规划&#xff0c;及《网络平台道路货物运输经营管理办法》等相关法律法…