算法28:力扣64题,最小路径和------------样本模型

题目:

给定一个二维数组matrix,一个人必须从左上角出发,最后到达右下角 。沿途只可以向下或者向右走,沿途的数字都累加就是距离累加和 * 返回累加和最小值

思路:

1. 既然是给定二维数组matrix,那么二维数组的数据是知道的

2. 这个人只能从左上角出发,目的地是右下角

3. 沿途只能向下或者向右走。那么第一行和第一列的值是可以知道的。

假设这个二维数组是:

3796
6539
8315
4792

根据这个二维数组推导:

第一行的数据只能往右走,因为它不存在上方数据,依此可以推导出:

3101925

第一列的数据,只能往下走,因为它不存在左边的数据,以此可以推导

310(3+7)19(10+9)25(19+6)
9(3+6)
17(9+8)
21(17+4)

已经推导出第一行和第一列的数据,接下来开始推导剩下的数据。因为每一个格子的数据都是依赖上一行的当前列或者当前行的前一列的值。谁小,就要谁。以此可以推导出:

3101925
914(9<10取 9+5)17(14<19 取14+3)26(17<25 取17+9)
1717(14<17 取14+3)1823(18<26 取 18+5)
2124 (17<21 取 17+7)27 (18<24 取 18+9)25 (23<27 取 23+2)

推导公式已经出来了。下面看代码的实现:

public static int minSum (int[][] matrix){if (matrix == null || matrix.length == 0) {return 0;}//行数int row = matrix.length;//列数int col = matrix[0].length;//如果是100*100规模的二维数组。那么dp的空间开销巨大int[][] dp = new int[row][col];//dp的第一行值只能依赖左边的值dp[0][0] = matrix[0][0];//构建dp表的第一行数据for (int colIndex = 1; colIndex < col; colIndex++) {//前一列和当前列的累加和,放入dp表dp[0][colIndex] = dp[0][colIndex -1] + matrix[0][colIndex];}//构建dp表的第一列数据for (int rowIndex = 1; rowIndex < row; rowIndex++) {//上一列和当前列的累加和,放入dp表dp[rowIndex][0] = dp[rowIndex -1][0] + matrix[rowIndex][0];}for (int rowIndex = 1; rowIndex < row; rowIndex++) {for (int colIndex = 1; colIndex < col; colIndex++) {//先获取上一行当前列 与 当前行的前一列 较小的值//获取matrix数组的当前行当前列的值//两者相加,就是 dp[rowIndex][colIndex]能够得到的最小值dp[rowIndex][colIndex] = Math.min(dp[rowIndex][colIndex -1], dp[rowIndex -1][colIndex]) + matrix[rowIndex][colIndex];}}return dp[row-1][col-1];}

以上代码是逐步推导的过程。但是,如果一个100行100列的数组需要推导,而且是要右下角的数据,中间数据是没有必要一直存在的。以上的代码浪费了 100*100的空间,并不是一个好的方式:

分析:

1. 第一行的数据是一定要的,因为根据第一行数据可以推导出第二行的数据

2. 第一列的数据是没有必要一次性全部推导出来的,因为每一个格子只依赖上一行的当前列和当前行的前一列。如果移动到当前行,直接更新当前行的第一列即可。

优化的代码:

//空间压缩进行优化public static int minSum2 (int[][] matrix){if (matrix == null || matrix.length == 0) {return 0;}//行数int row = matrix.length;//列数int col = matrix[0].length;// 空间压缩。// 二维数组变一维数组。int[] dp = new int[col];//构建dp表的第一行数据dp[0] = matrix[0][0];for (int colIndex = 1; colIndex < col; colIndex++) {//前一列和当前列的累加和,放入dp表dp[colIndex] = dp[colIndex -1] + matrix[0][colIndex];}for (int rowIndex = 1; rowIndex < row; rowIndex++) {//当前行第一列数据dp[0] += matrix[rowIndex][0];for (int colIndex = 1; colIndex < col; colIndex++) {dp[colIndex] = Math.min(dp[colIndex -1], dp[colIndex]) + matrix[rowIndex][colIndex];}}return dp[col -1];}

完整代码以及测试结果:

package code03.动态规划_07.lesson4;/*** 给定一个二维数组matrix,一个人必须从左上角出发,最后到达右下角* 沿途只可以向下或者向右走,沿途的数字都累加就是距离累加和* 返回累加和最小值*/
public class MinPathSum_01 {public static int minSum (int[][] matrix){if (matrix == null || matrix.length == 0) {return 0;}//行数int row = matrix.length;//列数int col = matrix[0].length;//如果是100*100规模的二维数组。那么dp的空间开销巨大int[][] dp = new int[row][col];//dp的第一行值只能依赖左边的值dp[0][0] = matrix[0][0];//构建dp表的第一行数据for (int colIndex = 1; colIndex < col; colIndex++) {//前一列和当前列的累加和,放入dp表dp[0][colIndex] = dp[0][colIndex -1] + matrix[0][colIndex];}//构建dp表的第一列数据for (int rowIndex = 1; rowIndex < row; rowIndex++) {//上一列和当前列的累加和,放入dp表dp[rowIndex][0] = dp[rowIndex -1][0] + matrix[rowIndex][0];}for (int rowIndex = 1; rowIndex < row; rowIndex++) {for (int colIndex = 1; colIndex < col; colIndex++) {//先获取上一行当前列 与 当前行的前一列 较小的值//获取matrix数组的当前行当前列的值//两者相加,就是 dp[rowIndex][colIndex]能够得到的最小值dp[rowIndex][colIndex] = Math.min(dp[rowIndex][colIndex -1], dp[rowIndex -1][colIndex]) + matrix[rowIndex][colIndex];}}return dp[row-1][col-1];}//空间压缩进行优化public static int minSum2 (int[][] matrix){if (matrix == null || matrix.length == 0) {return 0;}//行数int row = matrix.length;//列数int col = matrix[0].length;// 空间压缩。// 二维数组变一维数组。int[] dp = new int[col];//构建dp表的第一行数据dp[0] = matrix[0][0];for (int colIndex = 1; colIndex < col; colIndex++) {//前一列和当前列的累加和,放入dp表dp[colIndex] = dp[colIndex -1] + matrix[0][colIndex];}for (int rowIndex = 1; rowIndex < row; rowIndex++) {//当前行第一列数据dp[0] += matrix[rowIndex][0];for (int colIndex = 1; colIndex < col; colIndex++) {dp[colIndex] = Math.min(dp[colIndex -1], dp[colIndex]) + matrix[rowIndex][colIndex];}}return dp[col -1];}public static void main(String[] args) {int[][] arr = {{3,7,9,6},{6,5,3,9},{8,3,1,5},{4,7,9,2}};System.out.println(minSum(arr));System.out.println(minSum2(arr));}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/606708.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

寒假前端第一次作业

1、用户注册&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>用户注册</title> …

C++中的返回值优化(RVO)

一、命名返回值优化&#xff08;NRVO&#xff09; 是Visual C2005及之后版本支持的优化。 具体来说&#xff0c;就是一个函数的返回值如果是一个对象。那么&#xff0c;正常的返回语句的执行过程是&#xff0c;把这个对象从当前函数的局部作用域&#xff0c;或者叫当前函数的…

视频AI智剪方法:快速批量处理视频,批量剪辑视频的操作

随着科技的飞速发展&#xff0c;视频内容已是获取信息和娱乐的主要方式之一。对于视频创作者和内容生产者来说&#xff0c;如何快速、高效地处理和剪辑大量视频已成为一项重要的需求。现在借助AI技术的不断发展&#xff0c;可以更加智能、高效的处理视频。下面来看云炫AI智剪如…

VS2022 | 显示Unreal Engine日志

VS2022 | 显示Unreal Engine日志 视图 -> 其他窗口 -> Unreal Engine日志 视图 -> 其他窗口 -> Unreal Engine日志

【debug】为什么ansible中使用command出错

碎碎念 在使用ansible执行command的时候&#xff0c;遇到执行会出错的command 比如执行source打算读取环境变量的时候 错误提示为&#xff1a; 没有那个文件或目录:source 一开始以为是错误提示有问题&#xff0c;一直在testrc的路径上检查&#xff0c;但是同样一行命令使用…

一次因线程池使用不当造成生产事故OOM

美好的一天从bug结束 某日当我点开熟悉的界面&#xff0c;一个又一个请求失败的提示赫然出现在屏幕上&#xff0c;不会是昨晚上线的代码有问题吧&#xff1f; 吓得我急忙按F12查看了响应——"exception":"java.lang.OutOfMemoryError","message"…

院士专家齐聚 京彩未来联合重点研究院创建数字空间联合实验室

1月6日&#xff0c;京彩未来与北京大学数字中国研究院华南分院暨广东省数字广东研究院共同创建的“数字空间共同体联合室验室”正式挂牌运营。 著名经济学家管清友博士、北京大学数字中国研究院华南分院暨广东省数字广东研究院常务副院长李鹰教授&#xff0c;广东省数字广东研…

大数据 Hive - 实现SQL执行

文章目录 MapReduce实现SQL的原理Hive的架构Hive如何实现join操作小结 MapReduce的出现大大简化了大数据编程的难度&#xff0c;使得大数据计算不再是高不可攀的技术圣殿&#xff0c;普通工程师也能使用MapReduce开发大数据程序。 但是对于经常需要进行大数据计算的人&#xff…

蒙特卡洛算法

通过随机数获得结果的算法。 当一个问题无法通过数学推导&#xff0c;计算机无法在有限时间求解时候。 就需要考虑蒙特卡洛方法了。 当无法求得精确解时候&#xff0c;进行随机抽样&#xff0c;根据统计试验求近似解。 可行域过大&#xff0c;没有通用方法求出精确解。 主…

【设计模式】访问者模式

一起学习设计模式 目录 前言 一、概述 二、结构 三、案例实现 四、优缺点 五、使用场景 六、扩展 总结 前言 【设计模式】访问者模式——行为型模式。 一、概述 定义&#xff1a; 封装一些作用于某种数据结构中的各元素的操作&#xff0c;它可以在不改变这个数据结构…

linux安装codeserver实现云端开发

先看图 下载安装包 https://github.com/coder/code-server/releases 找到code-server-版本号-linux-amd64.tar.gz&#xff0c;我这里是code-server-4.16.1-linux-amd64.tar.gz 1、使用acrm用户登录目标服务器 2、切换root用户&#xff0c;创建 vscode 用户&#xff0c;并设…

STM32MP157D-DK1 STM32CubeID使用与M核开发

STM32MP157具有A7内核核M4内核&#xff0c;前面介绍的一些文章&#xff0c;都是在A7内核上进行的&#xff0c;本篇来介绍M4内核的开发&#xff0c;以及开发时要用到的STM32 CubeIDE软件的使用。 1 STM32 CubeIDE创建LED工程 STM32CubeIDE是一体式多操作系统开发工具&#xff…

云消息队列 Kafka 版生态谈第一期:无代码转储能力介绍

作者&#xff1a;娜米 云消息队列 Kafka 版为什么需要做无代码转储 云消息队列 Kafka 版本身是一个分布式流处理平台&#xff0c;具有高吞吐量、低延迟和可扩展性等特性。它被广泛应用于实时数据处理和流式数据传输的场景。然而&#xff0c;为了将云消息队列 Kafka 版与其他数…

linux日志管理

一.inode与block 访问文件的流程&#xff1a; 根据文件夹的文件名和inode号&#xff0c;找到对应的inode表&#xff0c;再根据inode表的指针找到磁盘上的真实数据 tips&#xff1a;我磁盘空间还剩很多&#xff0c;但是无法建立文件&#xff1f; 因为inode号被分完了 解决方法&a…

深度理解Flutter:有状态Widget与无状态Widget的详细对比

有状态Widget 什么是有状态Widget (StatefulWidget) 官方解释&#xff1a; 如果用户与 widget 交互&#xff0c;widget 会发生变化&#xff0c;那么它就是 有状态的。 有状态的 widget 自身是可动态改变的&#xff08;基于State&#xff09;。 例如用户交互而改变 Widget 的 s…

校招社招,认知能力测验,③如何破解语言常识类测试题?

作为认知能力测评中的一个环节&#xff0c;语言常识类&#xff0c;是大概率的出现&#xff0c;不同的用人单位可能略有不同&#xff0c;语言是一切的基础&#xff0c;而常识则意味着我们的知识面的宽度。 语言常识类的测试&#xff0c;如果要说技巧&#xff1f;难说....更多的…

洗地机什么牌子好?目前口碑最好的洗地机

如今&#xff0c;人们的生活中&#xff0c;洗地机已经成为了越来越受欢迎的清洁工具&#xff0c;洗地机能迅速而有效地清理地板、地毯以及其他硬表面&#xff0c;为用户提供更加方便快捷的洗地机体验。那么&#xff0c;洗地机什么牌子好?我们一起来看看目前口碑最好的洗地机有…

在Kubernetes中优雅地导出和清理Ingress资源

引言 Kubernetes的Ingress资源是定义外部访问集群服务的规则。随着微服务架构和容器化技术的普及&#xff0c;Ingress作为路由流量的关键组件变得愈发重要。当我们需要在环境之间迁移Ingress资源或者备份当前的配置时&#xff0c;就会用到导出功能。然而&#xff0c;直接使用k…

508基于51单片机的火灾检测与报警系统设计

基于51单片机的火灾检测与报警系统设计[proteus仿真] 火灾检测与报警系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个基于51单片机的火灾检测与报警系统设计 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文章 …

在云服务器ECS上用Python写一个搜索引擎

在云服务器ECS上用Python写一个搜索引擎 一、场景介绍二、搜索引擎的组成2.1 网页的爬取及排序2.2 用户使用搜索引擎进行搜索 三、操作步骤3.1 环境准备3.2 安装Anaconda3.3 安装Streamlit3.4 下载搜索引擎代码3.5 运行搜索引擎 四、常见问题4.1 运行setup.py时可能的问题4.2 如…