算法整理——【动态规划练习(8)子序列】

本博客我们梳理用动态规划方法解决子序列问题。

一、最长公共子序列

题目为1143. 最长公共子序列 - 力扣(LeetCode),给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。如果不存在公共子序列,返回 0 。

使用动规五部曲分析:

①确定dp数组和下标的含义。 本题dp[i][j]我将其设置为text1中[0,i]的字符串和text2中[0,j]的字符串的最长公共子序列。

②递推公式。主要分成两大类,text1[i]和text2[j]相同和不同两类。如果相同,则该元素为相同公共元素,此时dp数组的值应该长度增加1,那么我们在哪个基础上加一呢?我们应该在[0,i-1]和[0,j-1]的比较结果下加一,这样不会重复计算i和j位置上的元素,所以为dp[i][j] = dp[i-1][j-1]+1。如果i-1<0或者j-1<0,则将dp[i][j]设为1即可。如果不相同,说明该位置不能匹配,最长公共子序列保留之前的值,为dp[i-1][j]和dp[i][j-1]之间的较大值。

③初始化。全部初始化为0。

④遍历顺序。由递推公式得遍历顺序为从左到右从上到下。

⑤打印检查dp数组。

完整代码为:

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {vector<vector<int>> dp(text1.size(),vector<int>(text2.size(),0));for(int i = 0; i<text1.size(); i++){for(int j = 0; j<text2.size(); j++){if(text1[i] == text2[j]){if(j>0&&i>0) dp[i][j] = dp[i-1][j-1]+1;else dp[i][j] = 1;}else{if(j>0&&i>0) dp[i][j] = max(dp[i-1][j],dp[i][j-1]);if(j==0&&i>0) dp[i][j] = dp[i-1][j];if(i==0&&j>0) dp[i][j] = dp[i][j-1];}}}return dp[text1.size()-1][text2.size()-1];}
};

二、不相交的线

题目为1035. 不相交的线 - 力扣(LeetCode),虽然要求的是不相交的直线,但其实就是在找最长公共子序列,因为相同子序列顺序不改变,直线就不会相交。

代码与上一题完全相同:

class Solution {
public:int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {vector<vector<int>> dp(nums1.size(),vector<int>(nums2.size(),0));for(int i = 0; i<nums1.size(); i++){for(int j = 0; j<nums2.size(); j++){if(nums1[i] == nums2[j]){if(j>0&&i>0) dp[i][j] = dp[i-1][j-1]+1;else dp[i][j] = 1;}else{if(j>0&&i>0) dp[i][j] = max(dp[i-1][j],dp[i][j-1]);if(j==0&&i>0) dp[i][j] = dp[i-1][j];if(i==0&&j>0) dp[i][j] = dp[i][j-1];}}}return dp[nums1.size()-1][nums2.size()-1];}
};

同样的,用这个思路和方法还可以解决判断子序列问题。

三、最大子序和

题目为53. 最大子数组和 - 力扣(LeetCode),之前贪心算法中解决过这个题,现在我们用动态规划来尝试解决一下。

①dp数组和下标的含义。dp[i]表示包括下标i的数的最大连续子序列和。

②递推公式。dp[i]因为计算了nums[i],所以分为两种情况,在i-1的状态上加上nums[i]和以nums[i]开始计算,二者取较大值。

③初始化。初始化dp[0]为nums[0]。

④遍历顺序。从前往后。

⑤检查dp数组。

完整代码如下:

class Solution {
public:int maxSubArray(vector<int>& nums) {vector<int> dp(nums.size());dp[0] = nums[0];int m = nums[0];for(int i = 1; i<nums.size(); i++){dp[i] = max(dp[i-1]+nums[i],nums[i]);if(dp[i]>m) m = dp[i];}return m;}
};

四、不同的子序列

题目为115. 不同的子序列 - 力扣(LeetCode),给你两个字符串 s 和 t ,统计并返回在 s 的子序列中 t 出现的个数,结果需要对10^9+7取模。

如果本题求的是连续的,那就可以用KMP。我们使用动规五部曲分析这个题:

①dp数组和下标的含义。dp[i][j]表示t串中[0,i]与s中[0,j]的子序列匹配数。

②递推公式。dp[i][j]的值取决于t[i]和s[j]是否相等。如果相等,则分为两种情况,使用这两个字母的匹配,则匹配数为dp[i-1][j-1]。如果不使用这两个字母的匹配,则匹配数为dp[i][j-1]。dp[i][j]为这两个数相加。如果不相等,则匹配数为之前的dp[i][j-1]。这里如果不理解可以自己画一下二维数组,例如对于s=baegg和t=bag的情况下,二维数组为[[1,1,1,1,1],[0,1,1,1,1],[0,0,0,1,2]]。

③初始化。在我写本题的时候,还因为初始化出了点小错。这里我对第一列进行初始化。dp[0][0]的值取决于t[0]和s[0]是否相等,第一列剩余值均为0,因为是长度为一个以上的t问长度为1的s里是否有该子序列。第一列的计算在for循环中就不需要计算了因为值已经给出了。

④遍历顺序。我们根据递推公式知道遍历顺序应该为从左到右、从上往下。

⑤打印dp数组检查。本题自己多练几个二维数组自己找规律可以增强自己的理解。也可以换一种思路进行训练,例如可以尝试把s放在列,t放在行。

完整代码如下:

class Solution {
public:int numDistinct(string s, string t) {vector<vector<uint64_t>> dp(t.size(), vector<uint64_t>(s.size(),0));if(s[0]==t[0]) dp[0][0] = 1;else dp[0][0] = 0;for(int i = 0; i<t.size(); i++){for(int j = 1; j<s.size(); j++){if(t[i] == s[j]){if(i>0) dp[i][j] = dp[i][j-1]+dp[i-1][j-1];if(i==0) dp[i][j] = dp[i][j-1]+1;}else{dp[i][j] = dp[i][j-1];}}}return dp[t.size()-1][s.size()-1];}
};

注意本题是数据需要是无符号64位整数,即uint64_t或者unsigned long long。

说明:本文为作者整理知识点用于复习巩固,参考了代码随想录的讲解,有问题可以联系作者欢迎讨论~

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

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

相关文章

vxe-table——实现切换页码时排序状态的回显问题(ant-design+elementUi中table排序不同时回显的bug)——js技能提升

之前写的后台管理系统&#xff0c;都是用的antdelement&#xff0c;table组件中的【排序】问题是有一定的缺陷的。 想要实现的效果&#xff1a; antv——table组件一次只支持一个参数的排序 如下图&#xff1a; 就算是可以自行将排序字段拼接到列表接口的入参中&#xff0c…

解决Error: Not Found:Page[5][-1,81] at view.umd.min.js

场景说明&#xff1a; uniapp使用组件&#xff0c;在APP环境出现&#xff0c;在H5环境正常。单页面上多处使用该组件&#xff0c;使用同名参数设置数据&#xff0c;应用切换效果时&#xff0c;触发请求不同接口&#xff0c;返回数据格式不同。使用v-if时出现&#xff0c;使用v…

环信+亚马逊云科技服务:助力出海AI社交应用扬帆起航

随着大模型技术的飞速发展&#xff0c;AI智能体的社交体验得到了显著提升&#xff0c;AI社交类应用在全球范围内持续火热。尤其是年轻一代对新技术和新体验的热情&#xff0c;使得AI社交产品在海外市场迅速崛起。作为领先的即时通讯解决方案提供商&#xff0c;环信与亚马逊云科…

计算机体系结构|| 再定序缓冲(ROB)原理(6)

实验6 再定序缓冲&#xff08;ROB&#xff09;原理 6.1实验目的 &#xff08;1&#xff09;加深对指令级并行性及其开发的理解。 &#xff08;2&#xff09;加深对基于硬件的前瞻执行的理解。 &#xff08;3&#xff09;掌握 ROB 在流出、执行、写结果确认4 个阶段所进行的…

vue3 -layui项目-左侧导航菜单栏

1.创建目录结构 进入cmd,先cd到项目目录&#xff08;项目vue3-project&#xff09; cd vue3-project mkdir -p src\\views\\home\\components\\menubar 2.创建组件文件 3.编辑menu-item-content.vue <template><template v-if"item.icon"><lay-ic…

SQL injection UNION attacks SQL注入联合查询攻击

通过使用UNION关键字&#xff0c;拼接新的SQL语句从而获得额外的内容&#xff0c;例如 select a,b FROM table1 UNION select c,d FROM table2&#xff0c;可以一次性查询 2行数据&#xff0c;一行是a&#xff0c;b&#xff0c;一行是c&#xff0c;d。 UNION查询必须满足2个条…

医学深度学习与机器学习融合的随想

医学深度学习与机器学习融合的随想 近年来&#xff0c;深度学习&#xff08;图像类&#xff09;和机器学习在医学领域的应用取得了飞速发展&#xff0c;为医学影像分析、疾病诊断和预后预测等领域带来了革命性的变革。深度学习擅长从复杂数据中提取高层次特征&#xff0c;而机…

java面试题,有synchronized锁,threadlocal、数据可以设置默认值、把redis中的json转为对象

有面试题&#xff0c;有synchronized锁&#xff0c;threadlocal 一、面试题小记二、加锁synchronized1. 先看代码2. synchronized 讲解2.1. 同步代码块2.2. 同步方法2.3. 锁的选择和影响2.4. 注意事项2.5 锁的操作&#xff0c;手动释放锁&#xff0c;显式地获取锁&#xff08;属…

java中log4j.properties配置文件浅析

Log4J的配置文件(Configuration File)就是用来设置记录器的级别、存放器和布局的&#xff0c;它可按keyvalue格式的设置或xml格式的设置信息。通过配置&#xff0c;可以创建出Log4J的运行环境。 1、配置文件 Log4J配置文件的基本格式如下&#xff1a; #配置根Logger log4j.roo…

开源XDR-SIEM一体化平台 Wazuh (1)基础架构

简介 Wazuh平台提供了XDR和SIEM功能&#xff0c;保护云、容器和服务器工作负载。这些功能包括日志数据分析、入侵和恶意软件检测、文件完整性监控、配置评估、漏洞检测以及对法规遵从性的支持。详细信息可以参考Wazuh - Open Source XDR. Open Source SIEM.官方网站 Wazuh解决…

【策略模式在项目中的实际应用】

业务场景 最最近项目中有这样的一个业务场景&#xff1a; 用户下单->管理员审核->配送员接单->配送中->送达–>签收->完成 整个业务以这种流程的形式存在&#xff0c;每个流程状态的业务不一样&#xff0c;考虑到多种状态如果直接写一个接口肯定会嵌套太多…

第3节课:超链接与图片——HTML中的导航与视觉元素

目录 超链接 <a>&#xff1a;网页间的桥梁创建超链接超链接的属性 图片 <img>&#xff1a;为网页增添视觉元素使用图片图片的属性 锚点和页面导航锚点的使用 实践&#xff1a;创建一个包含超链接和图片的网页 结语 在网页设计中&#xff0c;超链接和图片是两个至关…

深入理解JS中的发布订阅模式和观察者模式

发布/订阅模式(Publish/Subscribe)和观察者模式(Observer Pattern)在概念上非常相似,都是用于实现对象之间的松耦合通信。尽管它们在实现细节和使用场景上有所不同,但核心思想是相通的。 观察者模式 直接通信:在观察者模式中,观察者(Observer)直接订阅主题(Subject…

数据库之数据表基本操作

目录 一、创建数据表 1.创建表的语法形式 2.使用SQL语句设置约束条件 1.设置主键约束 2.设置自增约束 3.设置非空约束 4.设置唯一性约束 5.设置无符号约束 6.设置默认约束 7.设置外键约束 8.设置表的存储引擎 二、查看表结构 1.查看表基本结构 2.查看建表语句 三…

为什么要学习网安技术?

学习网络安全&#xff08;网安&#xff09;技术在当今社会变得尤为重要&#xff0c;这主要源于以下几个方面的原因&#xff1a; 保护个人隐私&#xff1a;随着互联网的普及&#xff0c;个人信息如姓名、地址、电话号码、甚至银行账户信息等都在网络上留下了痕迹。学习网安技术可…

(十)Spring教程——Spring配置概述

目录 前言 1.Spring容器高层视图 2.基于XML的配置 前言 在使用Spring所提供的各项丰富而神奇的功能之前&#xff0c;必须在Spring IoC容器中装配好Bean&#xff0c;并建立好Bean和Bean之间的关联关系。Spring的配置文件已经很精简了&#xff0c;但是广大的开发者希望它做得更…

AV1技术学习:Transform Coding

对预测残差进行变换编码&#xff0c;去除潜在的空间相关性。VP9 采用统一的变换块大小设计&#xff0c;编码块中的所有的块共享相同的变换大小。VP9 支持 4 4、8 8、16 16、32 32 四种正方形变换大小。根据预测模式选择由一维离散余弦变换 (DCT) 和非对称离散正弦变换 (ADS…

免费分享一套微信小程序图书馆座位预约管理系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序图书馆座位预约管理系统(SpringBoot后端Vue管理端)&#xff0c;分享下哈。 项目介绍 随着移动互联网技术的飞速发展和智能设备的普及&#xff0c;图书馆服务模式正在经历深刻的变革。本论文旨在…

从PyTorch官方的一篇教程说开去(3.3 - 贪心法)

您的进步和反馈是我最大的动力&#xff0c;小伙伴来个三连呗&#xff01;共勉。 贪心法&#xff0c;可能是大家在处理陌生问题时候&#xff0c;最容易想到的办法了吧&#xff1f; 还记得小时候&#xff0c;国足请了位洋教练发表了一句到现在还被当成段子的话&#xff1a;“如…

第2章-数学建模

目录 一、数据类型 【函数】&#xff1a; &#xff08;1&#xff09;find()、rfind()、index()、rindex()、count() &#xff08;2&#xff09;split()、rsplit() &#xff08;3&#xff09;join() &#xff08;4&#xff09;strip()、rstrip()、lstrip() &#xff08;5&…