力扣动态规划基础版(矩阵型)

62.不同路径(唯一路径问题)

62. 不同路径icon-default.png?t=O83Ahttps://leetcode.cn/problems/unique-paths/

方法一:动态规划 

 找状态转移方程,也就是说它从左上角走到右下角,只能往右或者往下走,那么设置一个位置为(i,j)它只能从(i-1,j)或者(i,j-1)走过来那么它的状态转移方程就是除了这个还要去思考边界条件,如果i=0那么就不满足右侧的状态转移方程,同理j

= 0也不行,就是边上的那些数,可以考虑到边上的那些数都可以设置为1,也就是f(i,0)和f(0,j)都是1

class Solution {public int uniquePaths(int m, int n) {int[][] f = new int [m][n];for(int i = 0; i < m; i ++){f[i][0] = 1;}for(int j = 0; j < n ; j++){f[0][j] = 1;}for(int i = 1; i < m; ++i){for(int j = 1; j < n; ++j){f[i][j] = f[i -1][j]  + f[i][j -1];}}return f[m - 1][n - 1];}
}

优化空间复杂度:

这个唯一路径问题可以进行空间复杂度的优化 :由于 f(i,j) 仅与第 i 行和第 i−1 行的状态有关,因此我们可以使用滚动数组代替代码中的二维数组,使空间复杂度降低为 O(n)。

这个思路是。我们不需要存储每一个点,只需要存储它的上面一个点就行,再加上上一列的值即可,从第二行开始,每一行进行遍历只需要原始的值加上上一列的值。边界条件就是第一行都是1(很好想)

class Solution {public int uniquePaths(int m, int n) {//对于每一行,按列进行遍历//第一行先都设为1int f[] = new int[n];for(int i = 0; i < n; ++i){f[i] = 1;}//从第二行开始,对每一列进行遍历,它的f值只和它的前一列相关for(int i = 1; i < m; i++){for(int j = 1; j < n; j++){f[j]  += f[j - 1];//这个f[j]再每一次行遍历都更新,它就代表着上一次遍历的上一行的内容 }}return f[n - 1];}
}

方法二:排列组合

因为它只能向下走或者是向右走,所以就只有

从左上角到右下角的过程中,我们需要移动 m+n−2 次,其中有 m−1 次向下移动,n−1 次向右移动。因此路径的总数,就等于从 m+n−2 次移动中选择 m−1 次向下移动的方案数。实现这个排列组合的式子就行,其实实现这个技巧也是有讲究的,因为上面等于下面两个的和,所以位数是一样的,做一个循环,每一项相乘就行

class Solution {public int uniquePaths(int m, int n) {long ans = 1;for(int x =  n,y = 1; y < m; ++x,++y){ans = ans *x/y;}return (int)ans;}
}

64.最小路径和 

64. 最小路径和icon-default.png?t=O83Ahttps://leetcode.cn/problems/minimum-path-sum/还不错这道题自己写出来了,感觉就是前面那个题目的变式,状态转移方程就是第(i,j)个点的最小值由于只能向下或者向右,所以最小值就是它上面的或者左边的加上它自身的值。然后边界条件考虑(0,0),再考虑第一行和第一列。

class Solution {public int minPathSum(int[][] grid) {int m = grid.length;int n = grid[0].length;int dp[][] = new int [m][n];dp[0][0] = grid[0][0];for(int i = 1 ; i < m ;++i){dp[i][0] = dp[i -1][0] + grid[i][0];}for(int j = 1; j < n;++j){dp[0][j] = dp[0][j - 1] + grid[0][j];}for(int i = 1; i < m; i++){for(int j = 1; j < n; j++){dp[i][j] = grid[i][j] + Math.min(dp[i -1][j],dp[i][j - 1]);}}return dp[m -1][n -1];}
}

63.不同路径Ⅱ

63. 不同路径 IIicon-default.png?t=O83Ahttps://leetcode.cn/problems/unique-paths-ii/

这个其实大同小异,但是加了个障碍也就是说带障碍的要做个判断,如果他这是0,这条路就死了直接置为0

然后这次构建dp数组是多了一个空间确实好用 

class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int m = obstacleGrid.length;int n = obstacleGrid[0].length;int dp[][] = new int [m+1][n+1];dp[1][1] = 1;for(int i = 1; i < m + 1; ++i){for(int j = 1;j < n + 1; ++j){if(obstacleGrid[i -1][j -1] == 1){dp[i][j] = 0;}else{dp[i][j] = Math.max(dp[i][j],dp[i - 1][j]+dp[i][j -1]);//这里的max是为了dp[1][1]}}}return dp[m][n];}
}

做完了这个题我又回头看第62题,确实是这样创建数组更舒服,我就又写了一版62的题解

class Solution {public int uniquePaths(int m, int n) {int[][] f = new int [m + 1][n + 1];f[1][1] = 1;for(int i = 1; i < m + 1; ++i){for(int j = 1; j < n + 1; ++j){f[i][j] = Math.max(f[i -1][j]  + f[i][j -1],f[i][j]);}}return f[m][n];}
}

对于63题我觉得不能用这钟方式,因为如果这样设置他的转移方程是求最小值,这样的话边界是0的情况下都算进去了,就错误了。

120.三角形最小路径和

方法一:动态规划 

120. 三角形最小路径和icon-default.png?t=O83Ahttps://leetcode.cn/problems/triangle/看到这个题目有点恍惚了,感觉是和以前的题目没啥区别,状态转移方程也是很好想,就是这一个的最小值就是上面和上面的左边的最小值加上这个值的min,但是三角形边界的情况还是特殊一点,因为就是比如在第i行的第0个发现j-1到达不了,以及在第i行的第i个发现在第i-1行的第i列也到达不了,所以要考虑这个两边的边界情况。其他的部分还是很像的,还需注意的是triangle是数组想取值用get

 for(int i = 1; i < m; ++i){dp[i][0] = dp[i -1][0] + triangle.get(i).get(0);for(int j =1;j < i; ++j){dp[i][j] = Math.min(dp[i -1][j -1],dp[i -1][j]) +triangle.get(i).get(j);}dp[i][i] = dp[i - 1][i - 1] + triangle.get(i).get(i);}

class Solution {public int minimumTotal(List<List<Integer>> triangle) {int m = triangle.size();int [][] dp = new int [m][m];dp[0][0] = triangle.get(0).get(0);for(int i = 1; i < m; ++i){dp[i][0] = dp[i -1][0] + triangle.get(i).get(0);for(int j =1;j < i; ++j){dp[i][j] = Math.min(dp[i -1][j -1],dp[i -1][j]) +triangle.get(i).get(j);}dp[i][i] = dp[i - 1][i - 1] + triangle.get(i).get(i);}int minTol = dp[m -1][0];for(int i = 1; i < m; i++){minTol = Math.min(minTol,dp[m -1][i]);}return minTol;}
}

931.下降路径最小和

931. 下降路径最小和icon-default.png?t=O83Ahttps://leetcode.cn/problems/minimum-falling-path-sum/这道题目其实和上一道的思路属于是殊途同归的,需要考虑这些形状的边界的情况,与三角形不同,这个要考虑左右两边,容易出错的点就是在考虑右边的时候注意下标m -1同时考虑最后一排的最小值。做过上面那道题,这道题可以轻松ac

class Solution {public int minFallingPathSum(int[][] matrix) {int m = matrix.length;int dp[][]  = new int [m][m];//初始化for(int i = 0; i < m; ++i){dp[0][i] = matrix[0][i];}for(int i = 1; i < m; ++i){dp[i][0] = matrix[i][0] + Math.min(dp[i - 1][0],dp[i -1][1]); for(int j = 1; j < m - 1; ++j){dp[i][j] = matrix[i][j] + Math.min(Math.min(dp[i -1][j -1],dp[i -1][j]),dp[i -1][j + 1]);}dp[i][m - 1] = matrix[i][m -1] + Math.min(dp[i -1][m -1],dp[i -1][m -2]);}int minres = dp[m -1][0];for(int i = 0; i < m; ++i){minres = Math.min(minres,dp[m -1][i]);}return minres;}
}

221.最大正方形 

221. 最大正方形icon-default.png?t=O83Ahttps://leetcode.cn/problems/maximal-square/

方法一:暴力

暴力来说的话还是比较好想的,就是先遍历一遍,如果有1就设置为res为1了,然后就找到这个左上角,去算一下潜在的最大正方形,再去遍历去找,先沿着对角线如果是1的话,就再看看其他地方是否满足,设置flag,如果不满足置为false

class Solution {public int maximalSquare(char[][] matrix) {int m = matrix.length;int n = matrix[0].length;int res = 0;if(matrix == null || matrix.length == 0 || matrix[0].length == 0){return res;}for(int i = 0; i < m; ++i){for(int j = 0; j < n; ++j){if(matrix[i][j] == '1'){res = Math.max(1,res);//计算可能的最大的正方形边长int currentMaxside = Math.min(m - i,n - j);for(int k = 1 ;k < currentMaxside; ++k){//判断新增的一列是否都是1boolean flag = true; if(matrix[i + k][j + k] == '0'){break;}for(int q = 0; q < k; ++q){if(matrix[i + k][j + q] == '0' || matrix[i + q][j + k] == '0'){flag = false;break;}}if(flag){res = Math.max(res,k + 1);}else{break;}}}}}int ress = res * res;return ress;}
}

方法二:动态规划

这个就有点秒了,考虑的是用 dp(i,j) 表示以 (i,j) 为右下角,且只包含 1 的正方形的边长最大值。

如果该位置的值是 1,则 dp(i,j) 的值由其上方、左方和左上方的三个相邻位置的 dp 值决定。具体而言,当前位置的元素值等于三个相邻位置的元素中的最小值加 1。

这样的话状态转移方程就可以用下面式子来表示

然后注意边界条件就是,如果在第一排或者第一列,瑞国他是1的话,dp[i][j]只能为1 

dp[i][j] = Math.min(Math.min(dp[i -1][j],dp[i - 1][j -1 ]),dp[i][j -1]) + 1
class Solution {public int maximalSquare(char[][] matrix) {int Maxres = 0;int rows = matrix.length;int columns = matrix[0].length;int [][] dp = new int [rows][columns];for(int i = 0; i < rows; ++i){for(int j = 0; j < columns; ++j){if(matrix[i][j] == '1'){if(i == 0 || j == 0){dp[i][j] = 1;}else{dp[i][j] = Math.min(Math.min(dp[i -1][j],dp[i - 1][j -1 ]),dp[i][j -1]) + 1;}Maxres = Math.max(Maxres,dp[i][j]);}}}int Maxsquare = Maxres * Maxres;return Maxsquare;}
}

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

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

相关文章

算法(第一周)

一周周五&#xff0c;总结一下本周的算法学习&#xff0c;从本周开始重新学习许久未见的算法&#xff0c;当然不同于大一时使用的 C 语言以及做过的简单题&#xff0c;现在是每天一题 C 和 JavaScript&#xff08;还在学&#xff0c;目前只写了一题&#xff09; 题单是代码随想…

08 反射与注解

目录 1.Java类加载机制 类加载器 双亲委派模型 工作流程 优点 2.反射 基本概念 常见用法 1. 获取 Class 对象 2.获取构造方法 3.获取成员方法 4.获取成员变量 3.注解 注解的基本概念 定义和使用注解 定义注解 使用注解 解释 元注解详解 常见内置注解 总结…

【Linux第八课-进程间通信】管道、共享内存、消息队列、信号量、信号、可重入函数、volatile

目录 进程间通信为什么&#xff1f;是什么&#xff1f;怎么办&#xff1f;一般规律具体做法 匿名管道原理代码 命名管道原理代码 system V共享内存消息队列信号量信号量的接口 信号概念为什么&#xff1f;怎么办&#xff1f;准备信号的产生信号的保存概念三张表匹配的操作和系统…

【一些正经的思考】牵牛花在秋天播种可以开花吗

这是一篇正经的思考&#xff0c;因为是发生在工位上的事情&#xff0c;所以这也是上班记录~ 我入职新公司已经两个月了&#xff0c;和部门的新伙伴出去吃饭的频率高了1000%&#xff0c;不得不说&#xff0c;这边的食堂确实不是那么好吃&#xff0c;就和小伙伴经常去一个在江边…

零基础Java第十四期:继承与多态(二)

目录 一、继承 1.1. 继承的方式 1.2. final关键字 1.3. 继承与组合 1.4. protected关键字 二、多态 2.1. 多态的概念 2.2. 向上转型 2.3. 重写 2.4. 向下转型 2.5. 多态的优缺点 一、继承 1.1. 继承的方式 猫类可以继承动物类&#xff0c;中华田园猫类可以继承猫类…

RocketMQ 广播消息

所谓的广播消息就是发送的一条消息会被多个消费者收到。 ⼴播是向主题&#xff08; topic &#xff09;的所有订阅者发送消息。订阅同⼀个 topic 的多个消费者&#xff0c;能全量收到⽣产者发送的所有消息。 生产者发送了10个order&#xff0c;每个order里面有5个消息&#xff…

.Net IOC理解及代码实现

IOC理解 IoC(Inversion of Control)&#xff1a;即控制反转&#xff0c;这是一种设计思想&#xff0c;指将对象的控制权交给IOC容器&#xff0c;由容器来实现对象的创建、管理&#xff0c;程序员只需要从容器获取想要的对象就可以了。DI(Dependency Injection)&#xff0c;即依…

react的创建与书写

一&#xff1a;创建项目 超全面详细一条龙教程&#xff01;从零搭建React项目全家桶&#xff08;上篇&#xff09; - 知乎 1.创建一个文件夹&#xff0c;shift鼠标右键选择在此处打开powershell 2.为了加速npm下载速度&#xff0c;先把npm设置为淘宝镜像地址。 npm config s…

【微信小游戏学习心得】

这里是引用 微信小游戏学习心得 简介了解微信小游戏理解2d游戏原理数据驱动视图总结 简介 本人通过学习了解微信小游戏&#xff0c;学习微信小游戏&#xff0c;加深了对前端框架&#xff0c;vue和react基于数据驱动视图的理解&#xff0c;及浏览器文档模型和javaScript之间的关…

深究JS底层原理

一、JS中八种数据类型判断方法 在JavaScript中&#xff0c;数据类型分为两大类&#xff1a;基本&#xff08;原始&#xff09;数据类型和引用&#xff08;对象&#xff09;数据类型。 基本数据类型&#xff08;Primitive Data Types&#xff09; 基本数据类型是表示简单的数…

ssm071北京集联软件科技有限公司信息管理系统+jsp(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;北京集联软件科技有限公司信息管理系统 \ 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本信息…

Yocto 项目下通过网络更新内核、设备树及模块

Yocto 项目下通过网络更新内核、设备树及模块 前言 在 Yocto 项目的开发过程中&#xff0c;特别是在进行 BSP&#xff08;Board Support Package&#xff09;开发时&#xff0c;经常需要调整特定软件包的版本&#xff0c;修改内核、设备树以及内核模块。然而&#xff0c;每次…

k8s集群安装(kubeadm)

k8s集群安装&#xff08;kubeadm&#xff09; 1、环境准备&#xff08;master和node节点都执行&#xff09;1.1、替换yum源1.2、关闭selinux1.3、永久关闭防火墙1.4、永久关闭swap1.5、修改主机名添加host1.6、时间同步1.7、将桥接的IPv4流量传递到iptables的链1.8、docker安装…

【日常问题排查小技巧-连载】

线上服务CPU飙高排查 先执行 top&#xff0c;找到CPU占用比较高的进程 id&#xff0c;&#xff08;比如 21448&#xff09; jstack 进程 id > show.txt&#xff08;jstack 21448 > show.txt&#xff09; 找到进程中CPU占用比较高的线程&#xff0c;线程 id 转换为 16 进…

您与此网站之间建立的连接不安全解决方法

如果你打开网站&#xff0c;地址栏有警告&#xff0c;点进去是这样的提示&#xff1a;您与此网站之间建立的连接不安全&#xff0c;了解详细信息。 请勿在此网站上输入任何敏感信息&#xff08;例如密码或信用卡信息&#xff09;&#xff0c;因为攻击者可能会盗取这些信息。 …

【与AI+】学习SAP开发有什么渠道可以推荐

前言&#xff1a;好的&#xff0c;我又将开辟一个新的专栏&#xff0c;这个专栏呢&#xff0c;就准备放一些我向AI提问的问题&#xff0c;以及AI的回答。因为感觉真的好方便哈哈哈~ 我不是很确定我的专栏文章内容是否涉及版权&#xff0c;以及也不确定这些整合过的文字是否涉嫌…

江苏博才众创科技产业园集团拟投资10亿元在泰兴打造汽车零部件产业园

2024年11月7日&#xff0c;泰兴市高新技术产业开发区与江苏博才众创科技产业园集团举行新能源汽车零部件智能制造产业园项目签约仪式。 泰兴市高新区党工委委员、管理办副主任王峰表示&#xff1a;高新区是全市项目建设的主阵地&#xff0c;近年来聚焦高端化、智能化、绿色化&a…

【python】Flask

文章目录 1、Flask 介绍2、Flask 实现网页版美颜效果3、参考 1、Flask 介绍 Flask 是一个用 Python 编写的轻量级 Web 应用框架。它设计简单且易于扩展&#xff0c;非常适合小型项目到大型应用的开发。 以下是一些 Flask 库中常用的函数和组件&#xff1a; 一、Flask 应用对…

产品经理如何使用项目管理软件推进复杂项目按时上线

前言 相信很多产品同学或多或少都有过这样的经历&#xff1a;平时没有听到任何项目延期风险&#xff0c;但到了计划时间却迟迟无法提测……评审时没有任何argue&#xff0c;提测后发现开发的功能不是自己想要的……费劲九牛二虎之力终于让项目上线了&#xff0c;然而发现成果达…

新系统如何进行模型环境配置

在机器学习和深度学习中&#xff0c;一个良好的开发环境能够显著提高工作效率。本篇博客将详细介绍如何在新的Linux系统&#xff08;以Ubuntu为例&#xff09;上进行模型环境的配置&#xff0c;包括基础系统设置、Python虚拟环境搭建、常用库的安装以及GPU驱动和CUDA的安装等。…