代码随想录算法训练营DAY51|C++动态规划Part12|1143.最长公共子序列、1035.不相交的线、53.最大子序列和

本文主要是介绍代码随想录算法训练营DAY51|C++动态规划Part12|1143.最长公共子序列、1035.不相交的线、53.最大子序列和,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1143.最长公共子序列
    • 思路
    • CPP代码
  • 1035.不相交的线
  • 53.最大子序列和
    • 思路
    • CPP代码

1143.最长公共子序列

力扣题目链接

文章讲解:1143.最长公共子序列

视频讲解:动态规划子序列问题经典题目 | LeetCode:1143.最长公共子序列

本题其实就跟718.最长重复子数组类似,不要求连续了,但是还是要求相对顺序的。

思路

  • 确定dp数组下标及其含义

和之前718.最长重复子数组套路一样,唯一的区别只体现在递推公式中。我们还是使用一个二维dp来表达

dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]

  • 确定递推公式

主要就是两大情况: text1[i - 1]text2[j - 1]相同,text1[i - 1]text2[j - 1]不相同

如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1

如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。

即:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

  • dp数组如何初始化

先看看dp[i][0]应该是多少呢?

test1[0, i-1]和空串的最长公共子序列自然是0,所以dp[i][0] = 0

同理dp[0][j]也是0。

其他下标都是随着递推公式逐步覆盖,初始为多少都可以,那么就统一初始为0。

  • 确定遍历顺序

从递推公式可以看出,我们分别从三个方向(当前格的左上、左、上)来得出当前格的值

所以肯定是从前往后,从上到下遍历矩阵

  • 打印

以输入:text1 = “abcde”, text2 = “ace” 为例,dp状态如图:

CPP代码

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 {dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);}}}return dp[text1.size()][text2.size()];}
};

1035.不相交的线

力扣题目链接

文章讲解:1035.不相交的线

视频讲解:动态规划之子序列问题,换汤不换药 | LeetCode:1035.不相交的线

状态:把相同元素连成线,找出那些不相交的线,其实就是啥啊,求两个字符串的最长公共子序列长度

在上题中,我们已经讲过了1143.最长公共子序列

直接copy,就能通过

class Solution {
public:int maxUncrossedLines(vector<int>& A, vector<int>& B) {vector<vector<int>> dp(A.size() + 1, vector<int>(B.size() + 1, 0));for (int i = 1; i <= A.size(); i++) {for (int j = 1; j <= B.size(); j++) {if (A[i - 1] == B[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[A.size()][B.size()];}
}

53.最大子序列和

力扣题目链接

文章讲解:53.最大子序列和

视频讲解:看起来复杂,其实是简单动态规划 | LeetCode:53.最大子序和

状态:之前我们用贪心算法写过一次本题贪心算法:最大子序和,其实也很简单,这次用动规写一遍,也很简单

思路

  • dp数组含义

dp[i]:包括下标i(以nums[i]为结尾)的最大连续子序列和为dp[i]

  • 递推公式

dp[i]只有两个方向可以推出来:

  1. dp[i - 1] + nums[i],即:nums[i]加入当前连续子序列和

  2. nums[i],即:从头开始计算当前连续子序列和

一定是取最大的,所以dp[i] = max(dp[i - 1] + nums[i], nums[i]);

需要注意的是,本题的最大值可不一定存在与dp数组的最后一个元素,因为根据dp[i]的定义是以nums[i]为结尾)的最大连续子序列和。所以后续我们必须用一个容器来装dp数组的最大值,免得最后还要再遍历一遍。

dp[i] = max(dp[i - 1] + nums[i], nums[i]); // 状态转移公式
if (dp[i] > result) result = dp[i]; // result 保存dp[i]的最大值
  • 初始化

0下标初始化为nums[0]

其他均初始化为0

  • 遍历顺序

从小到大遍历

  • 打印

以示例一为例,输入:nums = [-2,1,-3,4,-1,2,1,-5,4],对应的dp状态如下:

CPP代码

class Solution {
public:int maxSubArray(vector<int>& nums) {if (nums.size() == 0) return 0;vector<int> dp(nums.size());dp[0] = nums[0];int result = dp[0];for (int i = 1; i < nums.size(); i++) {dp[i] = max(dp[i - 1] + nums[i], nums[i]); // 状态转移公式if (dp[i] > result) result = dp[i]; // result 保存dp[i]的最大值}return result;}
};

这篇关于代码随想录算法训练营DAY51|C++动态规划Part12|1143.最长公共子序列、1035.不相交的线、53.最大子序列和的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/957677

相关文章

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

go动态限制并发数量的实现示例

《go动态限制并发数量的实现示例》本文主要介绍了Go并发控制方法,通过带缓冲通道和第三方库实现并发数量限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录带有缓冲大小的通道使用第三方库其他控制并发的方法因为go从语言层面支持并发,所以面试百分百会问到

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

Spring的RedisTemplate的json反序列泛型丢失问题解决

《Spring的RedisTemplate的json反序列泛型丢失问题解决》本文主要介绍了SpringRedisTemplate中使用JSON序列化时泛型信息丢失的问题及其提出三种解决方案,可以根据性... 目录背景解决方案方案一方案二方案三总结背景在使用RedisTemplate操作redis时我们针对

MySQL进行数据库审计的详细步骤和示例代码

《MySQL进行数据库审计的详细步骤和示例代码》数据库审计通过触发器、内置功能及第三方工具记录和监控数据库活动,确保安全、完整与合规,Java代码实现自动化日志记录,整合分析系统提升监控效率,本文给大... 目录一、数据库审计的基本概念二、使用触发器进行数据库审计1. 创建审计表2. 创建触发器三、Java