当前位置: 首页 > news >正文

力扣HOT100之多维动态规划:1143. 最长公共子序列


这道题之前刷代码随想录的时候做过,但是现在又给忘干净了,这道题需要用二维dp数组来做,看了一下自己当时写的博客,一下子就看懂了。这道题的子序列可以不连续,所以dp数组的定义和最长重复子数组不一样,我总结出一个规律,**如果涉及到不连续的子序列,那么dp数组的定义就是第一个数组考虑[0,i]范围内元素,第二个数组考虑[0,j]范围内元素的情况下,两个数组之间的公共最长子序列的长度为dp[i][j];如果涉及到连续的子序列,那么dp数组的定义就是,第一个数组以nums1[i]结尾,第二个数组以nums2[j]结尾的情况下,所能得到的最长公共子序列的长度。**这道题还是要反复刷呀。
下面给出动规五部曲:
1.确定dp[i][j]的含义:text1考虑下标0 ~ i - 1范围内的元素,text2考虑下标0 ~ j - 1范围内的元素所能取到的最长公共子序列长度为dp[i][j]
(1)当text1[i - 1] == text2[j - 1]dp[i][j] = dp[i - 1][j - 1] + 1;
(2)当text1[i - 1] != text2[j - 1]dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
3.dp数组初始化 dp[0][0] = text1[0] == text2[0] ? 1 : 0;
4.确定遍历顺序:从左往右,从上往下遍历
5.打印数组(省略)
这里需要重点解释一下为什么dp数组要这样定义,因为假如我们这样定义:text1考虑下标0 ~ i范围内的元素,text2考虑下标0 ~ j范围内的元素所能取到的最长公共子序列长度为dp[i][j],那么我们在更新dp数组时,当text1[0] != text2[1]时,我们在执行dp[0][1] = max(dp[-1][1], dp[0][0]);时会发生越界访问,从而报错,我们很容易想到,我们无法将第0行和第0列通过简单的赋值进行初始化,这些元素的更新也需要借助复杂的递推公式,因此我们需要着重考虑如何在更新第0行和第0列时不发生越界访问,而将dp数组的下标与实际访问的字符串元素下标错开一位就能很好地解决这个问题。那么我们再回来看,当text1[0] != text2[1]时,我们会执行dp[1][2] = max(dp[0][2], dp[1][1]);那么dp[0][2]的初始值应该为多少?dp[0][2]的意义为:text1考虑下标0 ~ -1范围内的元素,text2考虑下标0 ~ 1范围内的元素所能取到的最长公共子序列长度为dp[0][2],很显然,text1没有合法元素可供比较,可以认为在这种情况下text1为空字符串,那么二者肯定不会存在公共子序列,因此dp[0][j]dp[i][0]都应全部初始化为0
至于递推公式,这个很容易想到,这里就不再赘述。

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {//1.确定dp[i][j]的含义:text1考虑下标0 ~ i - 1范围内的元素//text2考虑下标0 ~ j - 1范围内的元素所能取到的最长公共子序列长度为dp[i][j]//2.确定递推公式 //(1)当text1[i - 1] == text2[j - 1]时 dp[i][j] = dp[i - 1][j - 1] + 1;//(2)当text1[i - 1] != text2[j - 1]时 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);//3.dp数组初始化 dp[0][0] = text1[0] == text2[0] ? 1 : 0;//4.确定遍历顺序:从左往右,从上往下遍历//5.打印数组(省略)int m = text1.length();int n = text2.length();vector<vector<int>> dp(m + 1, vector<int> (n + 1, 0));  //初始化为全0数组for(int i = 1; i <= m; i++){for(int j = 1; j <= n; j++){if(text1[i - 1] == text2[j - 1])dp[i][j] = dp[i][j] = dp[i - 1][j - 1] + 1;elsedp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);}}return dp[m][n];}
};
http://www.xdnf.cn/news/787087.html

相关文章:

  • ArrayList 类
  • Generate Permutation
  • 编译器对齐机制与硬件浮点计算详解
  • 春雪食品×MTC AI助手:创新驱动再升级,效率革命正当时!
  • PV操作的C++代码示例讲解
  • .Net Framework 4/C# 初识 C#
  • LeetCode 300 最长递增子序列
  • 电工基础【5】简单的电路设计接线实操
  • SpringCloud——Nacos注册中心、OpenFeign
  • 前端验证下跨域问题(npm验证)
  • DeepSeek 赋能 NFT:数字艺术创作与交易的革新密码
  • 数据库完整性
  • 18.04 update 报错:(appstreamcli:2822): GLib-ERROR
  • 《Effective Python》第六章 推导式和生成器——使用类替代生成器的 `throw` 方法管理迭代状态转换
  • 提升系统稳定性和可靠性的特殊线程(看门狗线程)
  • Electron桌面应用下,在拍照、展示pdf等模块时,容易导致应用白屏
  • DiskGenius专业版v6.0.1.1645:分区管理、数据恢复、备份还原,一应俱全!
  • PHP+mysql 美容美发预约小程序源码 支持DIY装修+完整图文搭建教程
  • Vue3中使用Echarts图表步骤-demo
  • 安科瑞APD300:多模态融合的智能局放监测新标杆
  • PowerShell脚本编程基础指南
  • 01-python爬虫-第一个爬虫程序
  • Docker容器使用手册
  • AXURE安装+汉化-Windows
  • Ubuntu中TFTP服务器安装使用
  • 5.Transformer模型详解
  • SKUA-GOCAD入门教程-第八节 线的创建与编辑2
  • 后端解决跨域问题的三种方案:注解配置 vs 全局配置 vs 过滤器配置(附完整代码详解)
  • Spring 官方推荐构造函数注入
  • 通过阿里云 DashScope API 调用通义千问