news 2026/5/9 22:29:32

代码随想录算法训练营Day-44 动态规划11 | 1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
代码随想录算法训练营Day-44 动态规划11 | 1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列

1143.最长公共子序列

动规五部曲

dp数组含义:dp[i][j]代表text1中前i个元素部分和text2中前j个元素部分中的公共子序列最大长度。

递推公式:如果遇到text1[i-1] == text2[j-1]就继承dp[i-1][j-1],并在此基础上+1;

如果text1[i-1] != text2[j-1],就继承dp[i][j-1], dp[i-1][j]中的最大值。

初始化:全部初始化为0即可

遍历顺序:先text1还是text2都可

最终输出:和连续公共子序列不同,此题输出直接输出dp最右下角的元素

和最长连续公共子序列的区别:一个是连续的,只能在相等的时候继承,不可以删元素退回上一状态;

一个是不连续的,可以删元素,因此在不相等时也可以继承,退回上一状态就相当于删了元素,意思是,这个元素对匹配无作用,dp状态也一样。

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

1035.不相交的线

本题与上题完全一样,不相交直线数量和最长公共子序列长度一样。

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

53. 最大子序和

动规五部曲

dp数组含义:dp[i]代表以nums[i]为结尾的连续子数组所具有的最大和

递推公式:dp[i]从两个方向得来,一个是连上以nums[i-1]为结尾的最大和连续子数组,也就是dp[i-1]+nums[i],一个是不连上前面的(因为dp[i-1]可能是负的),直接只保留nums[i],二者选最大。

初始化:初始化dp[0]为nums[0],直接按照dp数组含义即可得到初始化值

遍历顺序:由于要从dp[i-1]向后推,所以顺序遍历,从1遍历到nums.size()-1

最终输出:需要遍历dp数组,寻找最大值

class Solution { public: int maxSubArray(vector<int>& nums) { //以nums[i]为结尾的连续子数组所具有的最大和 vector<int> dp(nums.size(),INT_MIN); dp[0] = nums[0]; int result = dp[0]; for(int i=1; i<nums.size(); i++){ dp[i] = max(nums[i], dp[i-1]+nums[i]); if(dp[i]>result) result = dp[i]; } return result; } };

392.判断子序列

花了几分钟写了一下双指针解法,好久没有用双指针,但还是凭借回忆写出来了,感觉之前的努力没有白费。

双指针

class Solution { public: bool isSubsequence(string s, string t) { int j=0; for(int i = 0;i<t.size()&&j<s.size();i++){ if(t[i] == s[j]) j++; } return j==s.size()?true:false; } };

动规写法

和最长公共子序列几乎一样,区别就在于,当s[i-1]!= t[j-1]时,不需要找dp[i][j-1]和dp[i-1][j]中的最大值,因为是找t里面有没有s的元素,所以当遇到s和t的元素不同时,不可以从s上退回,也就是不能删s的元素,只能删t的元素。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 22:29:16

P4 猴痘病识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 个人总结&#xff1a;本代码为猴痘病识别&#xff0c;核心对数据切分、网络结构及训练配置进行了优化&#xff0c;采用分层抽样&#xff08;train_test_splitst…

作者头像 李华
网站建设 2026/5/9 22:25:02

CANN/AMCT保存量化重训练模型

save_quant_retrain_model 【免费下载链接】amct AMCT是CANN提供的昇腾AI处理器亲和的模型压缩工具仓。 项目地址: https://gitcode.com/cann/amct 产品支持情况 产品 是否支持 Ascend 950PR/Ascend 950DT √ Atlas A3 训练系列产品 / Atlas A3 推理系列产品 √ Atlas…

作者头像 李华
网站建设 2026/5/9 22:24:21

怎样设置外键的更新级联操作_ON UPDATE CASCADE配置

ON UPDATE CASCADE 是 MySQL 外键约束中主表主键更新时自动同步子表外键值的机制&#xff0c;适用于主键为业务自然键且需批量变更的场景&#xff0c;必须配合索引使用并注意事务原子性。ON UPDATE CASCADE 是什么&#xff0c;什么时候必须用ON UPDATE CASCADE 是 MySQL 外键约…

作者头像 李华
网站建设 2026/5/9 22:21:36

VR手势识别硬件选型指南:从摄像头到肌电,四大方案深度解析

1. 项目概述&#xff1a;为什么硬件选型是VR手势识别的关键一步在沉浸式虚拟现实的世界里&#xff0c;我们追求的终极交互体验是“自然”。想象一下&#xff0c;你无需记忆复杂的按键组合&#xff0c;只需像在现实世界中一样&#xff0c;伸出手指、握拳、挥手&#xff0c;就能在…

作者头像 李华
网站建设 2026/5/9 22:20:31

独立开发者如何利用Taotoken模型广场为不同项目选型合适模型

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 独立开发者如何利用Taotoken模型广场为不同项目选型合适模型 作为独立开发者&#xff0c;你很可能同时负责多个项目&#xff1a;一…

作者头像 李华