【代码随想录day44】【C++复健】1143.最长公共子序列;1035.不相交的线;53. 最大子序和;392. 判断子序列

ops/2024/11/30 7:17:37/

1143.最长公共子序列

本题一开始以为是和前面那个一维递增子序列一样,dp数组的[i][j]表示的是以i,j为结尾的最长公共子序列,然后用两个for循环去前面找前缀对应的最大值,这样写出来的代码算上遍历总共要4次for循环,结果当然是会超时,并且我的代码还不知道哪里有问题,得不到正确的结果。

那么为什么本题用的是卡哥那样的定义方法,即:
1 如果当前位置相同,就是i-1,j-1位置的值+1
2 否则,取i-1,j和i,j-1的最大值。

这里引用一段在b站看到的评论的解释,由文无cc_大佬提供:

求递增序列的时候,因为要求序列有序,所以必须确定序列最后一个元素的值,才能比较新加入序列的元素是不是递增的。求相等序列的时候,如果求连续相等子序列,则还是要确定序列最后一个元素的值;但是本题求的是不必连续的相等子序列,就不需要知道序列最后一个元素的值,只要知道范围内相等的序列长度就行,新来的相等元素可以直接加在序列后面

也就是说我在算最长公共子序列的时候,是不需要去看序列最后一个元素到底是什么的,所以也就无需将dp数组定义成以i,j为结尾。

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {int m = text1.size();int n = text2.size();vector<vector<int>> dp(m+1, vector<int>(n+1));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-1][j-1] + 1;}else{dp[i][j] = max(dp[i][j-1], dp[i-1][j]);}}}return dp[m][n];}
};

1035.不相交的线

还真和上一题一模一样,错的也一一模一样:比较的时候要判断nums1[i-1] == nums2[j-1]而不是nums1[i] == nums2[j],隔了一会再写就又忘了。

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

53. 最大子序和

说实在的一看到这个题满脑子都是贪心,不贪心反而不会做了,自己仿照着贪心的写法写了个dp数组,写出来就是对的。解析里说dp比较直观,贪心比较难想,但我感觉这俩是一模一样的思路,只是写法不一样而已。

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

392. 判断子序列

本题也是一样,满脑子双指针,让我用dp写一个m*n复杂度的代码感觉就像杀了我一样难受,总是感觉这里能优化,那里能改一下,结果改了半天,循环逻辑倒是解决了,但是一些特殊的初始化和边界条件又出现问题了。
最后老老实实写了一个m*n复杂度的代码,还是这个适合我,之前简化了半天完全给自己绕进去了。

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


http://www.ppmy.cn/ops/137861.html

相关文章

【NLP】第三章:长短期记忆网络LSTM

三、长短期记忆网络LSTM 循环神经网络的特点就是拥有"记忆"&#xff0c;就是考虑历史信息&#xff0c;从历史信息中获取辅助当前的决策。 按记忆能力分&#xff1a;simple rnn(就是前面讲的简单rnn结构)、长短期记忆网络(LSTM)、门控循环单元(GRU)、以及双向RNN(Bi-…

shell脚本基础学习_总结篇(完结)

细致观看可以&#xff0c;访问shell脚本学习专栏&#xff0c;对应章节会有配图https://blog.csdn.net/2201_75446043/category_12833287.html?spm1001.2014.3001.5482 导语 一、shell脚本简介 1. 定义&#xff1a; 2. 主要特点&#xff1a; 3. shell脚本的基本结构 4. S…

快速搭建一个博客!!!“Halo框架深度优化:搭建你的个性化博客或网站”

目录 引言&#xff1a; 一. 首先服务器上去下载一个docker 1.可以参考官方地址&#xff1a; 2. 通过宝塔来一键安装&#xff01;&#xff01;&#xff01; 3.也可以自己下载&#xff01;&#xff01;&#xff01; 1.卸载旧版 2.配置Docker的yum库 3.安装Docker 4.启动和…

TypeScript 命名空间与模块

在 TypeScript 中&#xff0c;命名空间和模块是两种不同的代码组织方式&#xff0c;它们都旨在帮助你管理和维护大型代码库。命名空间提供了一种将相关功能组织在一起的方式&#xff0c;而模块则允许你将代码分解成可重用的单元。在本文中&#xff0c;我们将探讨命名空间和模块…

探索文件系统,Python os库是你的瑞士军刀

文章目录 探索文件系统&#xff0c;Python os库是你的瑞士军刀第一部分&#xff1a;背景介绍第二部分&#xff1a;os库是什么&#xff1f;第三部分&#xff1a;如何安装os库&#xff1f;第四部分&#xff1a;简单库函数使用方法1. 获取当前工作目录2. 改变当前工作目录3. 列出目…

利用Python爬虫阿里巴巴中国站获得跨境属性的详细指南

在全球化贸易的背景下&#xff0c;跨境电商成为了连接全球买家和卖家的重要桥梁。阿里巴巴中国站作为全球知名的B2B电子商务平台&#xff0c;提供了海量的商品信息&#xff0c;其中跨境属性信息对于跨境电商尤为重要。本文将详细介绍如何使用Python编写爬虫&#xff0c;从阿里巴…

Java WEB:从起源到现代的传奇之旅

Java Web 起源于上世纪 90 年代&#xff0c;随着网络和浏览器的飞速发展&#xff0c;Java 为应对动态处理网页的需求&#xff0c;推出了 Servlet 技术。 1. Servlet 出现之前 在 Servlet 出现之前&#xff0c;用户请求主要是静态资源&#xff0c;如 html、css 等。此时的网络…

利用Python爬虫获取店铺详情:从入门到实践

在这个信息爆炸的时代&#xff0c;数据的价值日益凸显。对于电商、市场分析等领域来说&#xff0c;获取和分析店铺数据是至关重要的。Python作为一种强大的编程语言&#xff0c;因其简洁的语法和丰富的库支持&#xff0c;成为了爬虫开发的不二之选。本文将带你从零开始&#xf…