LeetCode 1162. As Far from Land as Possible【多源BFS】中等
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。
为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。
由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。
你现在手里有一份大小为 n x n 的 网格 grid,上面的每个 单元格 都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地。
请你找出一个海洋单元格,这个海洋单元格到离它最近的陆地单元格的距离是最大的,并返回该距离。如果网格上只有陆地或者海洋,请返回 -1。
我们这里说的距离是「曼哈顿距离」( Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个单元格之间的距离是 |x0 - x1| + |y0 - y1| 。
示例 1:

输入:grid = [[1,0,1],[0,0,0],[1,0,1]]
输出:2
解释:
海洋单元格 (1, 1) 和所有陆地单元格之间的距离都达到最大,最大距离为 2。
示例 2:

输入:grid = [[1,0,0],[0,0,0],[0,0,0]]
输出:4
解释:
海洋单元格 (2, 2) 和所有陆地单元格之间的距离都达到最大,最大距离为 4。
提示:
n == grid.lengthn == grid[i].length1 <= n <= 100grid[i][j]不是0就是1
本题与542. 01 Matrix相同。
解法 多源BFS
这里不是求某一个海洋区域到陆地区域的最短路,而是求所有的海洋区域到陆地区域这个「点集」的最短路。显然这不是一个「单源」最短路问题(SSSP)。在我们学习过的最短路算法中,求解 SSSP 问题的方法有 Dijkstra 算法和 SPFA算法,而求解任意两点之间的最短路一般使用 Floyd 算法。那我们在这里就应该使用 Floyd 算法吗?
要考虑这个问题,我们需要分析一下这里使用 Floyd 算法的时间复杂度。我们知道在网格图中求最短路,每个区域(格子)相当于图中的顶点,而每个格子和上下左右四个格子的相邻关系相当于边,我们记顶点的个数为 V V V ,Floyd 算法的时间复杂度为 O ( V 3 ) O(V^3) O(V3) ,而这里 V = n 2 V = n^2 V=n2 ,所以 O ( V 3 ) = O ( n 6 ) O(V^3) = O(n^6) O(V3)=O(n6) ,显然是不现实的。
考虑 SSSP 是求一个源点到一个点集中所有点的最短路,而这个问题的本质是求某个点集到另一个点集中所有点的最短路,即「多源最短路」,我们只需要对 Dijkstra 算法或者 SPFA 算法稍作修改。这里以 Dijkstra 算法为例,我们知道堆优化的 Dijkstra 算法实际上是 BFS 的一个变形,把 BFS 中的队列变成了优先队列,在拓展新状态的时候加入了松弛操作。Dijkstra 的堆优化版本第一步是源点入队,我们只需要把它改成源点集合中的所有的点入队,就可以实现求「多源最短路」。
思考:为什么?
因为我们这样做相当于建立了一个超级源点 S S S ,这个点与源点集中的 s 0 , s 1 , s 2 ⋯ s ∣ V ∣ s_0, s_1, s_2 \cdots s_{|V|} s0,s1,s2⋯s∣V∣ 都有边,并且权都为 0 0 0 。这样求源点集到目标点集的最短路,就变成了求超级源点 S S S 到它们的最短路,于是又转化成了 SSSP 问题。
继续思考:海洋区域和陆地区域,应该哪一个作为源点集?
也许你分析出「我们需要找一个海洋区域,满足它到陆地的最小距离是最大」会把海洋区域作为源点集。考虑后续的实现,我们知道 Dijkstra 中一个 d d d 数组用来维护当前源点集到其他点的最短路,而对于源点集中的任意一个点 s s s , d [ s x ] [ s y ] = 0 d[s_x][s_y] = 0 d[sx][sy]=0 ,这很好理解,源点到源点的最短路就是 0 0 0 。如果我们把海洋区域作为源点集、陆地区域作为目标点集,假设 t t t 是目标点集中的一个点,算法执行结束后 d [ t x ] [ t y ] d[t_x][t_y] d[tx][ty] 就是海洋区域中的点到 t t t 的最短距离,但是我们却不知道哪些 t t t 是海洋区域点的「最近陆地区域」,我们也不知道每个 s s s 距离它的「最近陆地区域」的曼哈顿距离。
考虑我们把陆地区域作为源点集、海洋区域作为目标点集,目标点集中的点 t t t 对应的 d [ t x ] [ t y ] d[t_x][t_y] d[tx][ty] 就是海洋区域 t t t 对应的距离它的「最近陆地区域」的曼哈顿距离,正是我们需要的,所以应该把陆地区域作为源点集。最终只需要比出 d [ t x ] [ t y ] d[t_x][t_y] d[tx][ty] 的最大值即可。如果使用 Dijkstra 算法,那么在初始化 d 数组时,把每个元素预置为 INF,所以如果发现最终比出的最大值为 INF,那么就返回 − 1 -1 −1 。
由于这里的边权为 1 1 1 ,不如直接使用多源 BFS,在这里每个点都只会被松弛一次。
class Solution {
public:int maxDistance(vector<vector<int>>& grid) {int n = grid.size();queue<pair<int, int>> q;int MAX_VALUE = n + n;for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {if (grid[i][j] == 1) {grid[i][j] = 0;q.push({i, j});} else grid[i][j] = MAX_VALUE;}}int d[4][2] = {-1, 0, 1, 0, 0, -1, 0, 1};int ans = -1;while (!q.empty()) {auto [x, y] = q.front(); q.pop();for (int i = 0; i < 4; ++i) {int u = x + d[i][0], v = y + d[i][1];if (u >= 0 && u < n && v >= 0 && v < n && grid[x][y] + 1 < grid[u][v]) {// 只有海洋单元格的值会被更新,且一次性更新为到最近陆地单元格的距离grid[u][v] = grid[x][y] + 1;ans = max(ans, grid[u][v]);q.push({u, v});}}}return ans;}
};
复杂度分析:
- 时间复杂度: O ( m n ) O(mn) O(mn)
- 空间复杂度: O ( m n ) O(mn) O(mn) ,虽然我们是原地修改,但是使用队列时,如果都是 1 1 1 都是陆地,就全部要入队。
相关文章:
LeetCode 1162. As Far from Land as Possible【多源BFS】中等
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
【算法】二分查找(整数二分和浮点数二分)
二分查找也称折半查找(Binary Search),是一种效率较高的查找方法,时间复杂度为O(logN)。 二分查找采用了“分治”策略。使用二分查找时,数组中的元素之间得有单调性(升序或者降序)。 二分的模…...
git压缩/合并多次commit提交为1次commit提交
git压缩/合并N次commit提交为1次commit提交 假设有最近3次提交: commit_id1 commit_id2 commit_id3目标是把以上3次commit合并成1个commit,注意,最新的commit提交在最上面。 在git bash里面的操作步骤: (1࿰…...
【3519DV500】AI算法承载硬件平台_2.5T算力+AI ISP图像处理_超感光视频硬件方案开发
Hi3519DV500 内置双核 A55 ,提供高效、丰富和灵活的CPU 资源,以满足客户计算和控制需求。 Hi3519DV500集成了高效的神经网络推理引擎,最高2.5Tops NN算力,支持业界主流的神经 网络框架。神经网络支持完整的 API 和工具链…...
Linux系统基础服务启动的方法
服务,其实就是运行在操作系统后台的一个或者多个应用程序,为计算机系统或用户提供某项特定的服务。Linux系统运行的绝大多数服务都是需要安装才有的,例如FTP服务、httpd服务、MySQL、redis、Zookeeper、rabbitmq、vsftpd等等,那么…...
STM32 FLASH 读写数据
1. 《STM32 中文参考手册》,需要查看芯片数据手册,代码起始地址一般都是0x8000 0000,这是存放整个项目代码的起始地址 2. 编译信息查看代码大小,修改代码后第一次编译后会有这个提示信息 2.1 修改代码后编译,会有提示…...
excel功能区(ribbonx)编程笔记--1 初识功能区
再office2003版本以前,excel是具有菜单栏和工具栏的,再office2007及以后的版本中,界面中没有菜单栏和工具栏,使用功能区替换了菜单和工具栏。 您可能意识到自定义用户界面也变得更加困难,其实设置功能区并不会像您想像的那样困难,因为Microsoft也意识到必须有一种方式供开…...
电脑远程接入软件可以进行文件传输吗?快解析内网穿透
电脑远程接入软件的出现,让我们可以在两台电脑之间进行交互和操作。但是,很多人对于这些软件能否进行文件传输还存在一些疑问。下面的文章将解答这个问题。 1.电脑远程接入软件可以进行文件传输。传统上,我们可能会通过传输线或者移动存储设…...
react-native-webview使用postMessage后H5不能监听问题(iOS和安卓的兼容问题)
/* 监听rn消息 */ const eventListener nativeEvent > {//解析数据actionType、extraconst {actionType, extra} nativeEvent.data && JSON.parse(nativeEvent.data) || {} } //安卓用document,ios用window window.addEventListener(message, eventLis…...
通过LD_PRELOAD绕过disable_functions
LD_PRELOAD LD_PRELOAD是Linux/Unix系统的一个环境变量,它可以影响程序的运行时的链接,它允许在程序运行前定义优先加载的动态链接库。通过这个环境变量,可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖系统的函数…...
Python批量爬虫下载文件——把Excel中的超链接快速变成网址
本文的背景是:大学关系很好的老师问我能不能把Excel中1000个超链接网址对应的pdf文档下载下来。虽然可以手动一个一个点击下载,但是这样太费人力和时间了。我想起了之前的爬虫经验,给老师分析了一下可行性,就动手实践了。 没…...
Crimson:高性能,高扩展的新一代 Ceph OSD
背景 随着物理硬件的不断发展,存储软件所使用的硬件的情况也一直在不断变化。 一方面,内存和 IO 技术一直在快速发展,硬件的性能在极速增加。在最初设计 Ceph 的时候,通常情况下,Ceph 都是被部署到机械硬盘上&#x…...
【websocket】websocket-client 与 websockets
websocket-client websocket-client 是 websocket 客户端,提供了对ws低级API的访问。通过导入 websocket 库使用,websocket 库是基于事件驱动的设计模式,通过定义回调函数来处理接收到的消息、错误和连接关闭等事件。 优势: 兼容…...
Qt快速学习(一)--对象,信号和槽
目录 1.Qt概述 1.1 什么是Qt 2.2 手动创建 2.3 pro文件 2.4 一个最简单的Qt应用程序 3 第一个Qt小程序 3.1 按钮的创建 3.2 对象模型(对象树) 3.3 Qt窗口坐标体系 4 信号和槽机制 4.1 系统自带的信号和槽 4.2 自定义信号和槽 4.3信号槽的拓展 4…...
Qt6之如何为QDialog添加最大化和最小化按钮
在QDialog构造函数中添加以下几行代码: // 设置窗体最大化和最小化Qt::WindowFlags windowFlag Qt::Dialog;windowFlag | Qt::WindowMinimizeButtonHint;windowFlag | Qt::WindowMaximizeButtonHint;windowFlag …...
攻防世界-warmup
原题解题思路 只有一张图片,就查看源代码,有一个source.php。 查看source.php,白名单中还有一个hint.php。 hint.php告诉我们flag的位置ffffllllaaaagggg 但是直接跳转是没用的,构造payload。 http://61.147.171.105:55725/sourc…...
02__models
LangChain提供两种封装的模型接口 1.大规模语言模型(LLM):输入文本字符串,返回文本字符串 2.聊天模型:基于一个语言模型,输入聊天消息列表,返回聊天消息 Langchain的支持OpenAI、ChatGLM、Hu…...
MyBatis入门配置及CURD实现
目录 一、MyBatis简介 1. 什么是 MyBatis ? 2. MyBatis的特性 3. 什么是持久层框架? 二、MyBatis环境配置 2.1 创建maven工程 2.2 导入相关pom依赖 2.3 导入jdbc配置文件 2.4 Mybatis相关插件安装 3.5 Mybatis-cfg.xml 核心配置 2.6 引入Log4j2日志文件…...
《游戏编程模式》学习笔记(五)原型模式 Prototype Pattern
原型的定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 举个例子 假设我现在要做一款游戏,这个游戏里有许多不同种类的怪物,鬼魂,恶魔和巫师。这些怪物通过“生产者”进入这片区域,每种敌人…...
ansible案列之LNMP分布式剧本
LNMP分布式剧本 一:环境设置二:编写Nginx剧本准备nginx下载源准备配置文件并开放PHP的访问路径准备php测试页面编写nginx剧本 三:编写Mysql剧本编写密码获取脚本准备Mysql的yum源编写mysql剧本 四:准备PHP剧本准备两个配置文件编写…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
