java数据结构与算法刷题-----LeetCode1091. 二进制矩阵中的最短路径

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

文章目录

    • 广度优先+双分裂蛇

在这里插入图片描述
在这里插入图片描述

广度优先+双分裂蛇

双分裂蛇:是求二维表中从起点到终点的经典思路(也是求无权图的最短路径问题的经典解法)。创建两条分裂蛇,分别从起点和终点出发,两者相遇,则找到一条路径。时间复杂度理论上和单分裂蛇一样,但实际效率双分裂蛇更高。

  1. 分裂蛇的意思是:如果遇到分叉路,分裂蛇A可以分裂成对应数量的蛇,然后分头行动。
  2. 为什么双分裂蛇更快?因为只有一条蛇时,最坏情况下所有结点都走一遍才能找到最短路径
  3. 双分裂蛇,无论分裂多少,肯定是最短路径上的两条蛇最先相遇。所以两条蛇初次相遇的路径,就是最短路径。而不用像单分裂蛇那样,很有可能将所有路走一遍再比较才能知道哪条路最短

简单来说,单分裂蛇,它需要走的步数更多,因为它要自己从起点走到终点,因此分裂的蛇也就越多,访问的结点也就越多。
而双分裂蛇,两条蛇走的步数都是单分裂蛇的一半。所以两条蛇分裂的蛇会很少。访问的结点就少

举个例子,一张可以无限对折的0.0002米厚的纸,对折40次左右可以到月球,40次正好就是219902公里。而对折40次的一半左右,比如23次只有1.677公里。此时我搞两张纸各对折40次的一半,加起来是1.677+1.677 = 3.3公里左右

可见,219902公里是一张纸对折40次的结果3.3公里左右是两张纸对折40次一半20次左右的结果. 而回到分裂蛇的例子。一条蛇分裂40次,和两条蛇各分裂20次。谁访问的结点更少呢?

因此理论上,最坏情况下双分裂蛇和单分裂蛇都是n^2的时间复杂度,也就是每个结点访问两次,但是实际上,找最短路径,就和一张纸对折40次和两张纸对折20次的区别是一样的,只要路径足够长,双分裂蛇访问的结点个数,和单分裂蛇访问的结点个数根本不是一个量级,就像一张纸对折40次上月球,两张纸对折20次加起来走不出一个小区是一个道理。双分裂蛇的效率是比单分裂蛇高的。

但是无论单分裂蛇还是双分裂蛇,找最短路径,都满足:初次相遇的蛇所在路径为最短路径。

也就是,就算是单分裂蛇,也不需要所有路径走一遍统计路径长度,才能找出最短的
因为最短路径上的蛇一定会先最先到达。(前提是所有蛇的速度一样,都是大家一起一步一步走)

解题思路:时间复杂度O( n 2 n^2 n2),空间复杂度O( n 2 n^2 n2)
  1. 创建两个队列A和B,当做分裂蛇,分别从起点[0][0]和终点[n-1][n-1]出发,将两个结点分别入各自的队列
  2. A队列先走一步,情况允许就分裂。新分裂出的蛇额外走
  1. 一步的含义是,我可以向8个方向走,只要能走就走。
  2. 分裂:如果多个方向都满足条件,则进行分裂,让分裂的蛇到达指定地点(一步),然后将分裂的蛇全部入队列
  3. 但是新入队列的蛇,不可以继续处理,因为它们已经走了一步了
  1. 如果两个队列没有相遇,B队列也走一步,情况允许就分裂,新分裂的不走
  2. 直到两个队列中有蛇相遇,就结束程序。因为双分裂蛇的特点就是,最先相遇的两条蛇所在路径为最短路径
代码:会给出双分裂蛇和单分裂蛇的两版代码,除了蛇的数量不一样,剩余代码全部一样,可以很明显的看见,双分裂蛇的效率高多了,比单分裂蛇效率高了40%
  1. 双分裂蛇版本用时6ms
    在这里插入图片描述
class Solution {final static int[] dx = {1, 1, 1, 0, 0, -1, -1, -1};//右下,下,左下,右,左,右上,上,左上final static int[] dy = {1, 0, -1, 1, -1, 1, 0, -1};//右下,下,左下,右,左,右上,上,左上final static int SIGN_A = 2;//A队列走过的路的标识final static int SIGN_B = 3;//B队列走过的路的标识class Node {//队列中的结点,保存x和y坐标int x, y;public Node(int x, int y) {this.x = x;this.y = y;}}public int shortestPathBinaryMatrix(int[][] grid) {int n = grid.length;if(grid[0][0] == 1 || grid[n-1][n-1] == 1) return -1;else if(grid[0][0] == 0 && n == 1) return 1;int steps = 2;//走了多少步,两个队列(贪吃蛇)一起算//头尾队列,一个从头走,一个从尾巴走,两个队列相遇,就是一个答案Queue<Node> headQue = new LinkedList<Node>();Queue<Node> tailQue = new LinkedList<Node>();headQue.offer(new Node(0, 0));tailQue.offer(new Node(n-1, n-1));grid[0][0] = SIGN_A;grid[n-1][n-1] = SIGN_B;//两个队列一起走while(!headQue.isEmpty() && !tailQue.isEmpty()) {boolean encounter = nextStep(grid, headQue, SIGN_A);//A队列走一步,是否相遇B队列if(encounter) return steps;//如果相遇,则返回步数//没有相遇,则A队列步数+1steps++;//B队列走一步,是否相遇A队列encounter = nextStep(grid, tailQue, SIGN_B);if(encounter) return steps;steps++;}return -1;//如果一直没有相遇就返回-1}//走一步private boolean nextStep(int [][]grid, Queue<Node> que, int sign) {int n = grid.length;int size = que.size();while((size--) > 0) {//如果当前队列有结点(无论多少个),那么这些结点只走一步,不多走,也就是这些结点走了一步后,过程中新添加的结点,本次不考虑Node cur = que.poll();//出队列当前结点int x = cur.x, y = cur.y;//获取其坐标for(int i = 0; i < 8; ++i) {//8个方向按右下,下,左下,右,左,右上,上,左上的顺序走一下int nx = x + dx[i];int ny = y + dy[i];//如果下标越界,或者要走的这一方向==1(此路不通),或者要走的这一方向当前队列已经走过了grid[nx][ny] == sign,就跳过if(nx < 0 || nx >= n || ny < 0 || ny >= n || grid[nx][ny] == 1 || grid[nx][ny] == sign) continue;// 如果要走的方向遇到了另一个队列,则说明相遇if(grid[nx][ny] != 0) return true;//返回true//如果没有相遇,向当前方向走一步grid[nx][ny] = sign;que.add(new Node(nx, ny));//添加到队列继续}}return false;}
}
  1. 单分裂蛇版本,用时10ms
    在这里插入图片描述
class Solution {public int shortestPathBinaryMatrix(int[][] grid) {if(grid[0][0] != 0)return -1;if(grid.length == 1){if(grid[0][0] == 0) return 1;else return -1;}int[] dx = {-1, -1, -1, 0,  0, 1, 1, 1};int[] dy = {-1, 0, 1, -1, 1, -1, 0,1};int n = grid.length;// 记录坐标Queue<int[]> queue = new LinkedList();//单分裂蛇queue.offer(new int[]{0,0});//从起点开始grid[0][0] = 1;//走过的就标志为1int length = 0;//路径长度loop:while(queue.size() > 0){//如果还有分裂蛇存在int size = queue.size();//获取当前分裂蛇,这些分裂蛇可以进行分裂,然后走一步++length;//走一步+1个路径长度while((size--) > 0){//只有当前分裂蛇可以走一步,多条路可走就分裂,新的分裂蛇不可以走,如果使用queue.size()会将新的分裂蛇也处理了int[] pos = queue.poll();//依次获取这些现在存在的分裂蛇for(int i =0; i < 8; i++){//从8个方向走int x = pos[0] + dx[i];int y = pos[1] + dy[i];//如果这个方向可以走,并且没有分裂蛇走过if(x >=0 && y >= 0 && x < grid.length && y < grid.length && grid[x][y] == 0){queue.offer(new int[]{x,y});//就分裂一条蛇过去,这条分裂后新进入队列的蛇,本次不可以再处理grid[x][y] = length +1;//将此结点标志为已到达过,赋值为:路径长度+1//这里很重要,终点一定是最短路径的蛇先到,此时它会将这个结点标志为已到访过//后面在较长路径的蛇,不会覆盖这个值//如果当前分裂蛇是第一个到终点的,则他就是最短路径上的蛇if(x == grid.length-1 && y == grid.length-1) break loop;//跳出整个循环,不继续处理任何蛇}}}}return grid[n-1][n-1] <2 ? -1 : grid[n-1][n-1];//返回到终点的最短路径长度}
}

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

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

相关文章

Linux 学习之路--工具篇--yum

前面介绍了权限有关的内容&#xff0c;这里继续介绍有关Linux里面常用的工具之一yum 目录 一、简单介绍 <1> 源代码安装 <2>rpm 包安装 <3>yum / apt-get(ubuntu) 安装 二、简单使用 <1>安装包介绍 <2> yum 的基本指令 -- install <…

C++:数据类型—布尔(12)

布尔类型代表就是真和假&#xff08;bool&#xff09; 真就是1&#xff08;true&#xff09; 假就是0&#xff08;false&#xff09; 也可以任务非0即为真 bool 直占用1个字节大小 语法&#xff1a;bool 变量名 (true | false&#xff09; 提示&#xff1a;bool在后期判断也是…

Capture One Pro 23中文---颠覆性的图像编辑与色彩配置

Capture One Pro 23是一款功能强大且专业的RAW图像编辑处理软件。它拥有全球领先的色彩管理技术和精细的图像编辑工具&#xff0c;可以对图片进行多种精细调整&#xff0c;包括曝光、色温、对比度、锐度等&#xff0c;以满足用户特定的后期处理需求。此外&#xff0c;Capture O…

第二百三十一回

文章目录 1. 概念介绍2. 符号和平台2.1 符号2.2 平台 3. 问题与解决3.1 常见问题3.2 解决方法 4.内容总结 我们在上一章回中介绍了"关于intl报错的问题"相关的内容&#xff0c;本章回中将介绍不同平台上换行的问题.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1…

【3】3道链表力扣题:删除链表中的节点、反转链表、判断一个链表是否有环

3道链表力扣题 一、删除链表中的节点&#x1f30f; 题目链接&#x1f4d5; 示例&#x1f340; 分析&#x1f4bb; 代码 二、反转链表&#x1f30f; 题目链接&#x1f4d5; 示例&#x1f340; 分析① 递归② 迭代 三、判断一个链表是否有环&#x1f30f; 题目链接&#x1f4d5; …

C++中使用虚函数实现多态

虚函数是C中用于实现多态&#xff08;Polymorphism&#xff09;的重要特性。下面是关于虚函数的讲解和代码示例&#xff1a;### 虚函数的定义&#xff1a; 虚函数是在基类中声明为 virtual 的成员函数。 在派生类中重写&#xff08;override&#xff09;这个虚函数&#xff0c;…

数据结构与算法 循环双链表基本运算与对称算法

一、实验内容 1、实现循环双链表的各种基本运算的算法 &#xff08;1&#xff09;初始化循环双链表h &#xff08;2&#xff09;依次采用尾插法插入a,b,c,d,e元素 &#xff08;3&#xff09;输出循环双链表h&#xff1b; &#xff08;4&#xff09;输出循环双链表h长度&am…

物联网学习1、什么是 MQTT?

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级、基于发布-订阅模式的消息传输协议&#xff0c;适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它在物联网应用中广受欢迎&#xff0c;能够实现传感器、执行器和其它设备之间的高效通…

HSP_04章_扩展: 进制、位运算

文章目录 10. 扩展: 进制11. 位运算11.1 二进制在运算中的说明11.2 原码 反码 补码11.3位运算符11.3.1 ~按位取反11.3.2 &按位与11.3.3 ^按位异或11.3.4 |按位或11.3.5 << 左移11.3.6 >> 右移 10. 扩展: 进制 进制介绍 进制的转换 2.1 其他进制转十进制 二进…

面试八股——redis——集群

0. redis集群的方案 1.主从复制&#xff08;高并发读&#xff09; 一个主节点负责写操作&#xff08;增删改&#xff09;&#xff0c;多个从节点负责查操作。 主从复制是让主节点修改数据之后&#xff0c;将对应数据同步到从节点中。 2.哨兵模式&#xff08;实现高可用&#x…

Redis命令请求的执行过程(一)

命令请求的执行过程 概述 一个命令请求从发送到获得回复的过程中&#xff0c;客户端和服务器需要完成一系列操作。 例子 举个例子。如果我们使用客户端执行以下命令: 127.0.0.1:6379> SET KEY VALUE OK那么客户端发送SET KEY VALUE命令到获得回复OK期间&#xff0c;客户…

图片标注编辑平台搭建系列教程(6)——fabric渲染原理

原理 fabric的渲染步骤大致如下&#xff1a; 渲染前都设置背景图然后调用ctx.save()&#xff0c;存储画布的绘制状态参数然后调用每个object自身的渲染方法最后调用ctx.restore()&#xff0c;恢复画布的保存状态后处理&#xff0c;例如控制框的渲染等 值得注意的是&#xff0…

精品丨PowerBI负载测试和容量规划

当选择Power BI作为业务报表平台时&#xff0c;如何判断许可证的选择是否符合业务需求&#xff0c;价格占了主导因素。 Power BI的定价是基于SKU和服务器内核决定的&#xff0c;但是很多IT的负责人都不确定自己公司业务具体需要多少。 不幸的是&#xff0c;Power BI的容量和预期…

54 npm run serve 和 npm run build 输出的关联和差异

前言 通常来说 我们开发的时候一般会用到的命令是 “npm run serve”, “npm run build” 前者会编译当前项目, 然后将编译之后的结果以 node 的形式启动一个服务, 暴露相关业务资源, 因此 我们可以通过 该服务访问到当前项目 后者是编译当前项目, 然后做一下最小化代码的优…

第六讲 B+树索引

1 B树大家庭 有一种称为 B 树的特定数据结构&#xff0c;人们还使用该术语来泛指一类平衡树数据结构&#xff1a; B-Tree (1971)BTree (1973)B*Tree (1977?)B link-Tree (1981)Bε-Tree (2003)Bw-Tree (2013) 2 B树 BTree 是一种自平衡【self-balance】、有序【ordered】的…

文生图大模型Stable Diffusion的前世今生!

1、引言 跨模态大模型是指能够在不同感官模态(如视觉、语言、音频等)之间进行信息转换的大规模语言模型。当前图文跨模态大模型主要有&#xff1a; 文生图大模型&#xff1a;如 Stable Diffusion系列、DALL-E系列、Imagen等 图文匹配大模型&#xff1a;如CLIP、Chinese CLIP、…

LeetCode Python - 84. 柱状图中最大的矩形

目录 题目描述解法方法一方法二 运行结果方法一方法二 题目描述 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights …

pytorch常用的模块函数汇总(1)

目录 torch&#xff1a;核心库&#xff0c;包含张量操作、数学函数等基本功能 torch.nn&#xff1a;神经网络模块&#xff0c;包括各种层、损失函数和优化器等 torch.optim&#xff1a;优化算法模块&#xff0c;提供了各种优化器&#xff0c;如随机梯度下降 (SGD)、Adam、RMS…

手机投屏到windows11电脑

1 安装无线投影组件 2 电脑端打开允许其他设备投影的开关 3 手机找到投屏选项 4 手机搜索可用设备连接即可 这里的官方文档给的不太好,给了一些让人眼花撩乱的信息,以下是经过整合的有效信息

FL Studio21.2.3中文版软件新功能介绍及下载安装步骤教程

FL Studio21.2中文版的适用人群非常广泛&#xff0c;主要包括以下几类&#xff1a; FL Studio 21 Win-安装包下载如下: https://wm.makeding.com/iclk/?zoneid55981 FL Studio 21 Mac-安装包下载如下: https://wm.makeding.com/iclk/?zoneid55982 音乐制作人&#xff1a…