算法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.hqwc.cn/news/317095.html

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

相关文章

Vue - 多行文本“展开、收起”功能

TextClamp 使用 js 实现文本展开、收起&#xff0c;并非纯 CSS 实现。 Props&#xff1a; fontSize&#xff1a;Number&#xff0c;默认&#xff1a;14lines&#xff1a;Number&#xff0c;默认&#xff1a;1lineHeight&#xff1a;Number&#xff0c;默认&#xff1a;20 F…

获取网页信息

每次copy & paste总是很麻烦&#xff0c;现在有点问题&#xff0c;先记录下来。 需求&#xff1a;获取url 里Feature list&#xff0c;并输出表格形式 可以用Convert curl commands to code&#xff1a;得到get请求的header&#xff0c;cookie等 import requests import…

天然药物,到2028年市场规模将达到 3082亿美元

天然药物&#xff0c;也称为草药或传统药物&#xff0c;是指将植物、矿物和动物产品等天然物质用于药用目的。近年来&#xff0c;人们对天然药物作为传统药物的替代品越来越感兴趣&#xff0c;这导致了天然药物市场的增长。全球天然药物市场&#xff1a; 全球天然药物市场预计从…

八大算法排序@选择排序(C语言版本)

目录 选择排序概念算法思想示例步骤1步骤2步骤...n最后一步 代码实现时间复杂度空间复杂度特性总结 选择排序 概念 选择排序&#xff08;Selection Sort&#xff09;是一种简单直观的排序算法。基本思想是在未排序的序列中找到最小&#xff08;或最大&#xff09;元素&#xf…

VS2022 Android NativeActivity 开发指南

几年前最初使用VS时&#xff0c;记得是有Android NativeActivity的&#xff0c;今天更新到了2022最新版&#xff0c;发现找不到这个创建选项。 然后确保安装了C 跨平台开发工具后&#xff0c;开始排查原因。 Visual Studio 2022 中没有“本机活动应用程序” - android - SO中…

微信小程序 01

01.介绍 02.注册一个微信开发账户 官网https://mp.weixin.qq.com 03.下载开发工具 直接安装 04.登录开发者工具 先打开ide工具&#xff1a; 而后微信扫码&#xff0c;登录

clang-format

Clang-Format Clang-Format Style Options — Clang 18.0.0git documentation VSCode 1.1 安装扩展 C 1.2 设置 1.3 使用 .clang-fornat 放置在项目&#xff08;代码&#xff09;文件夹下使用 .clang-fornat 为文件名 --- # https://clang.llvm.org/docs/ClangFormatStyle…

java仓库管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web仓库管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…

STC进阶开发(三)蜂鸣器、RTC时钟、I2C总线、外部中断、RTC闹钟设置、RTC计时器设置

前言 这一期我们首先学习如何让蜂鸣器响起来&#xff0c;并且如何让蜂鸣器发出简单的歌曲&#xff0c;然后我们介绍RTC时钟&#xff0c;要想明白RTC时钟&#xff0c;我们还需要先介绍I2C总线和外部中断。接下来就开始这一期的学习吧&#xff01; 蜂鸣器 简单介绍 蜂鸣器是一种…

AntDB设计之CheckPoint——引言与功能简述

1.引言 数据库服务能力提升是一项系统性的工程&#xff0c;在不同的应用场景下&#xff0c;用户对于数据库各项能力的关注点也不同&#xff0c;如&#xff1a;读写延迟、吞吐量、扩展性、可靠性、可用性等等。国内不少数据库系统通过系统架构优化、硬件设备升级等方式&#xf…

echarts实现控制图(设置阈值上下限超出变色)

echarts实现控制图组件&#xff0c;拓展超出阈值变色显示&#xff0c;图中标记平均值及最大值和最小值 代码如下&#xff1a; <template><div :class"className" :style"{height:height,width:width}" /> </template><script>im…

2024.1.2 Redis 数据类型 Stream、Geospatial、HyperLogLog、Bitmaps、Bitfields 简介

目录 引言 Stream 类型 Geospatial 类型 HyperLogLog 类型 Bitmaps 类型 Bitfields 类型 引言 Redis 最关键&#xff08;应用广泛、频繁使用&#xff09;的五个数据类型 StringListHashSetZSet 下文介绍的数据类型一般适合在特定的场景中使用&#xff01; Stream 类型 St…