Leecode---多维动态规划---不同路径 / 最小路径和 /最长公共子序列

2024-06-02 17:12

本文主要是介绍Leecode---多维动态规划---不同路径 / 最小路径和 /最长公共子序列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
动态规划—三部曲
1、确定dp数组以及下标含义
dp[i][j]:表示从(0,0)出发,到(i,j)有dp[i][j]条不同的路径
2、确定递推公式
dp[i][j] = dp[i-1][j] + dp[i][j-1]
3、dp数组的初始化
如何初始化,dp[i][0]一定都是1,因为从(0,0)到(0,i)的路径只有一条,dp[0][j]同理:

for (int i = 0; i<m; i++) dp[i][0] = 1;
for (int j = 0; j<n; j++) dp[0][j] = 1;

知识点补充:二维容器vector< vector > 初始化方法解析:

vector<vector<int>> table(size1, vector<int>(size2, 0));

代码说明:声明一个名为table的容器,其元素为vector的容器。简单来说类似一个int型的二维数组。
这样,就得到了一个如下图所示的二维容器。
在这里插入图片描述
理解如下
在这里插入图片描述
图中,将外围容器table的初始化参数分成了两部分A、B。
A: table外围容器的大小
B: table外围容器的内容,即size1个vector型的元素。
B1:内部容器的大小
B2:内部容器的内容

同理:三维容器初始化:
定义一个长宽高为2x3x5的立方体容器,每个元素为0:

//长宽高:2*3*5 vector<vector<vector<int>>> cube(5, vector<vector<int>>(3, vector<int>(2, 0)));

C++代码如下

class Solution
{
public:int uniquePaths(int m, int n){// 声明一个名为dp的容器,其元素为vector的容器,类似一个int型的二维数组。vector<vector<int>> dp(m, vector<int>(n,0));for (int i = 0; i<m; i++) dp[i][0] = 1;for (int j = 0; j<n; j++) dp[0][j] = 1;for (int i = 1; i<m; i++){for(int j = 1; j<n; j++){dp[i][j] = dp[i-1][j] + dp[i][j-1];}}return dp[m-1][n-1];}
};

解法二、深搜(超时但同样容易理解)
机器人走过的路径可以抽象为一棵二叉树,而叶子节点就是终点!
在这里插入图片描述
此时问题就可以转化为求二叉树叶子节点的个数,代码如下:

class Solution
{
private:int dfs(int i, int j, int m, int n){if(i>m || j>n) return 0;	//越界if(i == m && j == n) return 1;	// 找到一种方法,相当于找到了叶子节点return dfs(i+1, j, m, n) + dfs(i, j+1, m, n);}
public:int uniquePaths(int m, int n){return dfs(1,1,m,n);}
};

在这里插入图片描述
动态规划—三部曲
1、确定dp数组以及下标含义
dp(i,j):表示从(0,0)出发,到(i,j)的最小路径和
2、确定递推公式(转移方程)
左位置和上位置的最短路径和的最小值,加上当前位置的值:
dp(i,j) = min{dp(i-1,j), dp(i,j-1)} + arr[i][j]
3、dp数组的初始化
最左一列和第一行的所有位置都必须作为初始值,防止递推越界。
dp(0,j) = dp(0, j-1) + arr[0][j]
dp(i,0) = dp(i-1, 0) + arr[i][0]
返回值:返回数组右下角的值dp(m-1, n-1)

class Solution
{
public:int minPathSum(vector<vector<int>>& grid){int row = grid.size();int col = grid[0].size();// 初始化for(int i = 1; i<row; i++)grid[i][0] += grid[i-1][0];for(int j = 1; j<col; j++)grid[0][j] += grid[0][j-1];// dp 过程for(int i = 1; i<row; i++){for(int j = 1; j<col; j++){grid[i][j] += min(grid[i-1][j], grid[i][j-1]); }}return grid[row-1][col-1];}
};

在这里插入图片描述
动态规划—三部曲:
1、确定字符串 f 及下标含义
定义 f[i][j] 表示字符串 text1 的 [1][i] 区间和字符串 text2 的 [1][j] 区间的最长公共子序列长度(下标从 1 开始)
2、初始化:
f[i][0] = f[0][j] = 0,(0 <= i <= n, 0 <= j <= m)
空字符串与有长度的字符串的最长公共子序列长度为0。
3、状态转移方程
① text1[i] == text2[j],即两字符串最后一位相等,此时问题转化为text1的[1, i-1]区间和字符串text2的[1, j-1] 区间的最长公共子序列长度再加一,即:
f[i][j] = f[i-1][j-1] + 1 (下标从1开始)
② text1[i] != text2[j], 即两字符串的最后一位不相等,此时 f[i][j] 会继承 f[i-1][j] 与 f[i][j-1] 中的较大值,即:
f[i][j] = max(f[i-1][j], f[i][j-1]) 。(下标从1开始)

为什么下标从1开始:
由状态转移方程f[i][j] = max(f[i-1][j], f[i][j-1]),当从1开始时,代码中不用对下标越界问题做额外判断。题目给的是从0开始,因此判断条件往前错一位,使用 text1[i-1] 和 text2[j-1] 判断。

class Solution
{
public:int longestCommonSubsequence(string text1, string text2){int n = text1.size(), m = text2.size();// 初始化if(m==0 && n==0) return 0;// 初始化二维容器vector<vector<int>> f(n+1, vector<int>(m+1, 0));for(int i = 1; i<=n; i++){for(int j = 1;j<=m; j++){// 状态转移矩阵if(text1[i-1] == text2[j-1]){f[i][j] = f[i-1][j-1] + 1;}else{f[i][j] = max(f[i-1][j],f[i][j-1]);}}}return f[n][m];}
};

这篇关于Leecode---多维动态规划---不同路径 / 最小路径和 /最长公共子序列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

VSCode设置python SDK路径的实现步骤

《VSCode设置pythonSDK路径的实现步骤》本文主要介绍了VSCode设置pythonSDK路径的实现步骤,包括命令面板切换、settings.json配置、环境变量及虚拟环境处理,具有一定... 目录一、通过命令面板快速切换(推荐方法)二、通过 settings.json 配置(项目级/全局)三、

使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形)

《使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形)》字体设计和矢量图形处理是编程中一个有趣且实用的领域,通过Python的matplotlib库,我们可以轻松将字体轮廓... 目录背景知识字体轮廓的表示实现步骤1. 安装依赖库2. 准备数据3. 解析路径指令4. 绘制图形关键

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL

如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)

《如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)》:本文主要介绍如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)问题,具有很好的参考价值,希望对大家有所帮助,如有... 目录先在你打算存放的地方建四个文件夹更改这四个路径就可以修改默认虚拟内存分页js文件的位置接下来从高级-

利用Python实现时间序列动量策略

《利用Python实现时间序列动量策略》时间序列动量策略作为量化交易领域中最为持久且被深入研究的策略类型之一,其核心理念相对简明:对于显示上升趋势的资产建立多头头寸,对于呈现下降趋势的资产建立空头头寸... 目录引言传统策略面临的风险管理挑战波动率调整机制:实现风险标准化策略实施的技术细节波动率调整的战略价

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht