leetcode每日一题--矩阵中移动的最大次数

 一.题目原型

 

 二.思路解析

1.动态规划

这道题要求的是矩阵的最大移动次数。根据题目意思,从索引 0 列开始向右移动,每次移动一列,最多移动到 n - 1 列,也就是 n - 1次。其移动规则为:当前单元格可以移动到其右上方、正右方以及右下方三个位置中严格大于其的单元格。那么换个角度想,一个单元格可以从其左上方、正左方以及左下方的单元格转移过来。

这不就是我们动态规划最开始的典型思路吗?

在这题中,我们从第一列开始,往后能走多少,到了第几列,其实就是这一次的走的步数,走到最远的列,就是最大的移动次数。

我们创建一个二维dp数组,初始化为0,我们从不同行的第一列元素开始走,能走到的地方我们做一个标记为1,已经标记过的我们就不再去走了,以免死循环。

int m=grid.size(),n=grid[0].size(),max_j=0;vector<vector<int>>dp(m,vector<int>(n,0));for(int i=0;i<m;++i){//初始化dp[i][0]=1;}

 dp【i】【j】由dp【i-1】【j-1】和dp【i】【j-1】和dp【i+1】【j】决定

for(int j=1;j<n;++j){//从第1列开始for(int i=0;i<m;++i){if((dp[i][j-1]==1&&grid[i][j]>grid[i][j-1])||(i-1>-1&&dp[i-1][j-1]==1&&grid[i][j]>grid[i-1][j-1])||(i+1<m&&dp[i+1][j-1]==1&&grid[i][j]>grid[i+1][j-1])){dp[i][j]=1;max_j=j;}}}

2.深度优先遍历

从第一列的任一单元格 (i,0)开始递归。枚举往右上/右/右下三个方向走,如果走一步后,没有出界,且格子值大于 grid[i][j],则可以走,继续递归。

在递归过程中,记录能访问到的最大列号,作为答案。

代码实现时,为避免重复递归之前访问过的格子,可以用一个 vis 数组标记访问过的格子。但实际上,可以把 grid[i][j]置为 0从而无需创建 vis数组。这是因为网格值均为正数,并且我们只能访问到比当前格子值更大的格子,所以置为 0 会导致永远无法访问到该格子,这正是我们所希望的。grid[i][j]置为0,表示这个点我们已经走过了,之后没有必要再走了,因为再往这个点走,移动的次数都是一样的。标记后就肯定不会再走了,因为要往后走的一个条件就是后面的点的值大于当前点的值。

function<void(int, int)> dfs = [&](int i, int j) {ans = max(ans, j);if (ans == n - 1) { // ans 已达到最大值return;}// 向右上/右/右下走一步for (int k = max(i - 1, 0); k < min(i + 2, m); k++) {if (grid[k][j + 1] > grid[i][j]) {dfs(k, j + 1);}}grid[i][j] = 0;};

3.广度优先遍历

同样,我们也可以使用BFS的方法,我们首先将所有的行坐标加入集合中,表示这些地方都可以走,作为出发点。然后依次进行遍历,找到下一列可以走到的所有行坐标,这些下一列的行坐标都是严格满足比其走过来的点值要大的,然后将这些行坐标的集合替换掉之前的集合,再进行遍历,找到下一列能够走到的行坐标。直到没有能走的行坐标,或者走到最后一列为止。

我们需要一个vis数组去标记走过的位置,不能再走了

定义一个判断坐标合法的函数is_valid去判断坐标是不是合法的。

三.代码实现:

动态规划(DP)

class Solution {
public:int maxMoves(vector<vector<int>>& grid) {int m=grid.size(),n=grid[0].size(),max_j=0;vector<vector<int>>dp(m,vector<int>(n,0));for(int i=0;i<m;++i){//初始化dp[i][0]=1;}for(int j=1;j<n;++j){//从第1列开始for(int i=0;i<m;++i){if((dp[i][j-1]==1&&grid[i][j]>grid[i][j-1])||(i-1>-1&&dp[i-1][j-1]==1&&grid[i][j]>grid[i-1][j-1])||(i+1<m&&dp[i+1][j-1]==1&&grid[i][j]>grid[i+1][j-1])){dp[i][j]=1;max_j=j;}}}return max_j;}
};

深度优先遍历(DFS)

class Solution {
public:int maxMoves(vector<vector<int>> &grid) {int m = grid.size(), n = grid[0].size();int ans = 0;function<void(int, int)> dfs = [&](int i, int j) {ans = max(ans, j);if (ans == n - 1) { // ans 已达到最大值return;}// 向右上/右/右下走一步for (int k = max(i - 1, 0); k < min(i + 2, m); k++) {if (grid[k][j + 1] > grid[i][j]) {dfs(k, j + 1);}}grid[i][j] = 0;};for (int i = 0; i < m; i++) {dfs(i, 0); // 从第一列的任一单元格出发}return ans;}
};

广度优先遍历(BFS)

class Solution {
public:int maxMoves(vector<vector<int>>& grid) {int M = grid.size(), N = grid[0].size();auto is_valid = [&](int r, int c) -> bool {return 0 <= r && r < M && 0 <= c && c < N;};queue<pair<int, int>> que;vector<vector<bool>> vis(M, vector<bool>(N, false));for (int r = 0; r < M; r++) {vis[r][0] = true;que.push(make_pair(r, 0));}int ans = 0;while (!que.empty()) {auto [r, c] = que.front(); que.pop();ans = max(ans, c);int ce = c+1;for (const int& re : {r-1, r, r+1}) {if (is_valid(re, ce) && !vis[re][ce] && grid[r][c] < grid[re][ce]) {vis[re][ce] = true;que.push(make_pair(re, ce));}}}return ans;}
};

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

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

相关文章

2核4g服务器够用吗?

2核4G服务器够用吗&#xff1f;够用。阿腾云以2核4G5M服务器搭建网站为例&#xff0c;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户同时在1秒内打开网站&#xff0c;并发数为10&am…

SqlServer2008(R2)(一)SqlServer2008(R2)经典宝藏操作收集整理

一、常见操作 1、TRUNCATE TABLE 语句 删除表数据 TRUNCATE TABLE语句比DELET删除表中的所有行更快。从逻辑上讲&#xff0c;TRUNCATE TABLE它类似于DELETE没有WHERE子句的语句。 TRUNCATE TABLE语句从表中删除所有行&#xff0c;但表结构及其列&#xff0c;约束&#xff0c;…

​​SQLiteC/C++接口详细介绍之sqlite3类(十一)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;​​SQLiteC/C接口详细介绍之sqlite3类&#xff08;十&#xff09; 下一篇&#xff1a;​​SQLiteC/C接口详细介绍之sqlite3类&#xff08;十二&#xff09;&#xff08;未发表&#xff09; 33.sq…

flink1.18.0报错 an implicit exists from scala.Int => java.lang.Integer, but

完整报错 type mismatch;found : Int(100)required: Object Note: an implicit exists from scala.Int > java.lang.Integer, but methods inherited from Object are rendered ambiguous. This is to avoid a blanket implicit which would convert any scala.Int to a…

T1.数据库MySQL

二.SQL分类 2.1 DDL 2.1.1数据库操作 1). 查询所有数据库 show databases ; 2). 查询当前数据库 select database(); 3)创建数据库 create database [if not exists] 数据库名 [default charset 字符集] [collate 排序规则] ; 4&#xff09;删除数据库 drop database …

无人机助力智慧农田除草新模式,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建无人机航拍场景下的农田杂草检测识别系统

科技发展到今天&#xff0c;无人机喷洒药物已经不是一件新鲜事情了&#xff0c;在很多高危的工作领域中&#xff0c;比如高空电力设备除冰&#xff0c;电力设备部件传送更换等等&#xff0c;无人机都可以扮演非常出色的作用&#xff0c;前面回到老家一段时间&#xff0c;最近正…

高效使用 JMeter 生成随机数:探索 Random 和 UUID 算法

在压力测试中&#xff0c;经常需要生成随机值来模拟用户行为。JMeter 提供了多种方式来生成随机值&#xff0c;本文来具体介绍一下。 随机数函数 JMeter 提供了多个用于生成随机数的函数&#xff0c;其中最常用的是__Random函数。该函数可以生成一个指定范围内的随机整数或浮…

wsl or 虚拟机 安装

1.wsl2安装 WSL全称Windows Subsystem for Linux&#xff0c;是微软开发的适用于Linux的Windows子系统 如今已经有两代了&#xff1a; 所以用的多的还是wsl2。 安装前需要先去设置启用或关闭Windows功能&#xff1a; 打开适用于linux的子系统和虚拟机平台。 Microsoft Store里…

k8s之图形界面DashBoard【九】

文章目录 9. DashBoard9.1 部署Dashboard9.2 使用DashBoard 镇场 9. DashBoard 之前在kubernetes中完成的所有操作都是通过命令行工具kubectl完成的。其实&#xff0c;为了提供更丰富的用户体验&#xff0c;kubernetes还开发了一个基于web的用户界面&#xff08;Dashboard&…

spring boot集成redis实现共享存储session

spring boot集成redis实现共享存储session redis实现共享存储session 首先下载redis,我下载的版本是5.0.14,目前官网貌似找不到5.x版本&#xff0c;可以自行去网上寻找。我这里的springboot版本是2.6.4引入redis依赖 <!-- https://mvnrepository.com/artifact/org.spring…

【刷题训练】牛客:JZ31 栈的压入、弹出序列

文章目录 一、题目要求二、解题思路三、C代码四、注意点五、运行成功 一、题目要求 二、解题思路 题意解读。本道题给定了两个序列pushV和popV&#xff0c;其中序列pushV是入栈顺序&#xff0c;popV是出栈顺序。问题就是让我们去判断这个popV的顺序是否可能是pushV的弹出顺序。…

基于Java+SpringMvc+vue+element实现驾校管理系统详细设计

基于JavaSpringMvcvueelement实现驾校管理系统详细设计 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末…