目录

1. 岛屿数量

1.1 题目解析

1.2 解法

1.3 代码实现

2. 岛屿的最大面积

2.1 题目解析

2.2 解法

2.3 代码实现


1. 岛屿数量

https://leetcode.cn/problems/number-of-islands/

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例 1:

输入:grid = [['1','1','1','1','0'],['1','1','0','1','0'],['1','1','0','0','0'],['0','0','0','0','0']
]
输出:1

示例 2:

输入:grid = [['1','1','0','0','0'],['1','1','0','0','0'],['0','0','1','0','0'],['0','0','0','1','1']
]
输出:3

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] 的值为 '0' 或 '1'

1.1 题目解析

题目本质

  • 在一个 m×n 的 0/1 网格上,统计由上下左右连通的“1”块的个数;本质是“连通分量计数(四联通)”。

常规解法

  • 朴素想法:对每个为 ‘1’ 的格子启动一次遍历,把与之相连的 ‘1’ 都标记掉,然后计数 +1。遍历可用 DFS 或 BFS。

问题分析

  • 如果不做“访问标记(vis)”,同一块岛屿会被重复启动遍历 → 重复计数/超时。

  • 如果标记时机不当(入队后不立刻标记),同一坐标会被多次入队 → 队列暴涨。

  • 边界获取不当(先取 grid[0].length 再判断空矩阵)会 NPE。

  • 复杂度:每格最多访问一次,理想是 O(mn);只要保证“入队(或递归)前标记”为时机,就不会退化。

思路转折

  • 要高效、且不重算:

    • 必须维护 vis[m][n] 访问标记;

    • 必须把标记动作放在“入队/入栈前”;

    • 必须只在遇到“未访问的 ‘1’”时启动一次 BFS/DFS,并在启动点处给计数器 +1。

  • 这样“每个格子至多被处理一次”,时间 O(mn)、空间 O(mn)。

1.2 解法

算法思想

  • 遍历整个网格;每当遇到 grid[i][j]=='1' && !vis[i][j]:

    • 启动一轮 BFS;

    • BFS 中用队列弹出当前格,向四邻扩展,对满足边界且为 ‘1’ 且未访问的坐标:先标记 vis=true,再入队;

    • 该轮 BFS 结束后,说明整块岛屿已被吞并,计数 ret++。

i)初始化

  • m = grid.length;若 m==0 直接返回 0。

  • n = grid[0].length;vis = new boolean[m][n];ret = 0。

ii)扫描网格

  • 双层循环 (i,j);当 grid[i][j]=='1' && !vis[i][j] 时,启动 BFS(i,j)。

iii)BFS 过程

  • 队列入起点 (si,sj),立刻标记 vis[si][sj]=true。

  • 不断出队 (a,b),向四方向 (a+dx[k], b+dy[k]) 扩展;满足:

    • 在边界内、

    • 未访问、

    • 且为 ‘1’
      先标记再入队。

    • 队列清空即该岛处理完毕,ret++。

iiii)返回 ret。

易错点

  • n = grid[0].length 必须放在 m==0 判空之后,否则空矩阵会 NPE。

  • if (grid[i][j]=='1' && !vis[i][j]) 中的 !vis[i][j] 一开始当然都是 true,但第一轮 BFS 会把整块岛都标记为 true,后续再遇到同岛格子就不会重复启动 BFS。

  • 标记时机要在入队前/时,否则同一坐标可能被多次入队。

  • 只统计“第一次发现这块岛”的那一刻(启动 BFS 时)的一次 ret++

  • 注意字符比较用 '1',不要写成 1

  • 四方向遍历下标不要写错。

  • 不要重复无意义的标记(出队后再次 vis[a][b]=true 属于冗余)。

1.3 代码实现

import java.util.*;class Solution {int[] dx = {0, 0, 1, -1};int[] dy = {1, -1, 0, 0};int m, n;Queue<int[]> q = new LinkedList<>();boolean[][] vis;int ret;public int numIslands(char[][] grid) {m = grid.length;if (m == 0) return 0;            // 先判空,再取 nn = grid[0].length;vis = new boolean[m][n];ret = 0;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == '1' && !vis[i][j]) {bfs(grid, i, j);    // 一次 BFS 吞并一整块岛}}}return ret;}// BFS:以 (si, sj) 为起点吞并整块岛屿public void bfs(char[][] grid, int si, int sj) {q.clear();                       // 成员队列:显式清空更稳妥q.offer(new int[]{si, sj});vis[si][sj] = true;              // 入队前/时标记,避免重复入队while (!q.isEmpty()) {int[] cur = q.poll();int a = cur[0], b = cur[1];for (int k = 0; k < 4; k++) {int x = a + dx[k], y = b + dy[k];if (x >= 0 && x < m && y >= 0 && y < n&& !vis[x][y] && grid[x][y] == '1') {vis[x][y] = true;     // 先标记,再入队q.offer(new int[]{x, y});}}}ret++;                            // 本轮 BFS 结束 → 发现了一座岛}
}

复杂度分析

  • 时间复杂度:O(m·n),每个格子最多被入队/出队一次,四邻检查是常数。

  • 空间复杂度:O(m·n),主要在 vis;队列最坏可能装下整层边界上的若干格子,但受 O(mn) 上界。

2. 岛屿的最大面积

https://leetcode.cn/problems/max-area-of-island/

给你一个大小为 m x n 的二进制矩阵 grid 。

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

示例 1:

输入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
输出:6
解释:答案不应该是 11 ,因为岛屿只能包含水平或垂直这四个方向上的 1

示例 2:

输入:grid = [[0,0,0,0,0,0,0,0]]
输出:0

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • grid[i][j] 为 0 或 1

2.1 题目解析

题目本质

  • 在 m×n 的二值矩阵中,按四联通把为 1 的格子聚合成若干连通分量,返回所有分量的最大节点数,也就是最大岛屿面积。

常规解法

  • 线性扫描整张表,每当遇到未访问的 1,就从该点出发做一次搜索,把整座岛吞并,并统计面积。可用 BFS 或 DFS。

问题分析

  • 如果不做访问标记,同一岛会被多次重复遍历,时间爆炸。

  • 如果标记时机晚(入队后才标记,甚至出队后才标记),同一坐标可能被多次入队,导致队列暴涨。

  • 如果把面积计数放在“发现邻居”时,会漏掉起点,得到 N−1 而不是 N。

  • 判空顺序不当会空指针,例如先取 grid[0].length 再判断 m 是否为 0。

  • 复杂度目标是 O(mn),只要保证每格最多被访问一次即可。

思路转折

  • 要想稳定 O(mn):

    • 需要全局 vis 数组去重。

    • 需要在入队之前标记 vis,保证每格最多入队一次。

    • 需要把面积计数与“访问到一个新格子”绑定,最简单是出队时加一。

    • 只在遇到 grid[i][j] == 1 且未访问时启动一次搜索,吞并整座岛并更新答案。

2.2 解法

算法思想

  • 双层循环扫描网格,遇到未访问的 1 启动 BFS。

  • BFS 初始化把起点入队并立刻标记已访问。

  • 循环弹出队头,面积加一,向四个方向扩展,把满足边界、为 1、未访问的邻居先标记后入队。

  • 本轮队列清空即整座岛处理完毕,用该岛面积更新全局最大值。

i)初始化

  • m = grid.length,若 m == 0 直接返回 0。

  • n = grid[0].length,初始化 vis[m][n] 为 false。

  • 准备一个整型答案 ret 保存最大面积。

ii)扫描

  • 双层循环 i, j。

  • 当且仅当 grid[i][j] == 1 且 vis[i][j] 为 false 时,启动 BFS(i, j)。

iii)BFS 细节

  • 入队起点并立刻标记 vis[si][sj] = true。

  • while 队列非空:

    • 弹出一个格子,面积加一。

    • 四方向扩展,满足边界、为 1、未访问的邻居先标记再入队。

  • 返回本轮面积。

iiii)更新答案

  • ret = max(ret, 本轮面积)。

iiiii)返回 ret

易错点

  • 判空顺序:必须先判断 m 是否为 0,再读取 grid[0].length。

  • 标记时机:必须在入队之前标记,防止同一坐标被多次入队。

  • 面积计数位置:推荐在出队时加一,这样每访问一个格子恰好计一次;如果坚持在“发现邻居”时计数,必须把起点先计入,否则会少一。

  • 邻居入队坐标:入队的是邻居 (x, y),不要误把起点 (si, sj) 重新塞回队列。

  • 只考虑四联通,不能把对角线当作连通。

  • 类型与比较:本题 grid 是 int[][],比较用 1 与 0;与 char[][] 的版本不要混用。

2.3 代码实现

import java.util.*;class Solution {Queue<int[]> q = new LinkedList<>(); // 成员队列,BFS 开始时清空更稳妥int m, n;boolean[][] vis;int[] dx = {0, 0, 1, -1};int[] dy = {1, -1, 0, 0};public int maxAreaOfIsland(int[][] grid) {m = grid.length;if (m == 0) return 0;        // 先判空,避免 NPEn = grid[0].length;vis = new boolean[m][n];int ret = 0, cur = 0;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == 1 && !vis[i][j]) {cur = 0;                         // 可有可无,这里保持你的风格int tmp = bfs(grid, i, j, cur);  // BFS 返回本岛面积ret = Math.max(ret, tmp);}}}return ret;}// BFS 吞并以 (si, sj) 为起点的整座岛,返回其面积public int bfs(int[][] grid, int si, int sj, int cur) {q.clear();                     // 成员队列,使用前先清空q.offer(new int[]{si, sj});vis[si][sj] = true;while (!q.isEmpty()) {int[] num = q.poll();int a = num[0], b = num[1];cur++;                     // 出队即计数,保证每格计一次for (int i = 0; i < 4; i++) {int x = a + dx[i], y = b + dy[i];if (x >= 0 && x < m && y >= 0 && y < n&& grid[x][y] == 1 && !vis[x][y]) {vis[x][y] = true;          // 入队前标记q.offer(new int[]{x, y});  // 入队邻居坐标}}}return cur;}
}

复杂度分析

  • 时间复杂度:O(mn),每个格子最多被访问一次,四邻检查是常数。

  • 空间复杂度:O(mn),主要为 vis;队列最坏情况下也不超过 O(mn)。

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

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

相关文章

短波红外相机在机器视觉检测方向的应用

短波红外相机在机器视觉检测方向的应用短波红外相机&#xff1a;机器视觉的“低成本突破者”一、打破成本困局&#xff1a;短波红外的“平民化”革新二、核心技术&#xff1a;有机材料的“硬核创新”1. 材料革命&#xff1a;有机感光层的优势2. 工艺兼容&#xff1a;嫁接成熟CM…

【数据结构与算法】图 Floyd算法

相关题目&#xff1a; 1334. 阈值距离内邻居最少的城市 - 力扣&#xff08;LeetCode&#xff09; 资料 &#xff1a; Floyd算法原理及公式推导 - 知乎 Floyd 算法是一种经典的动态规划算法&#xff0c;用与求解图中所有顶点之间的最短短路路径。它由Robert Floyd 于1962…

卫星通信天线的指向精度,含义、测量和计算

卫星通信天线的指向精度&#xff0c;含义、测量和计算我们在卫星通信天线的技术规格书中&#xff0c;都会看到天线指向精度这个指标。一般来说&#xff0c;技术规格书上的天线指向精度的参数是这么写的&#xff1a;“天线指向精度≤1/10半功率波束带宽”今天这个文章&#xff0…

基于LSTM与3秒级Tick数据的金融时间序列预测实现

数据加载模块解析 def load_data(filepath):df pd.read_csv(filepath)return df该函数承担基础数据采集职责&#xff0c;通过Pandas库读取CSV格式的高频交易数据&#xff08;典型如股票分笔成交明细&#xff09;。输入参数为文件路径字符串&#xff0c;输出结构化DataFrame对象…

C# --- Field and Property

C# --- Field and Property字段 (Field) vs. 属性 (Property)Property的声明初始化方法单例类property错误初始化导致线程泄漏字段 (Field) vs. 属性 (Property) 字段 (Field) - 数据的存储容器 字段是直接在类或结构中声明的变量。它是存储数据的地方&#xff0c;是对象状态的…

【Python】实现一个文件夹快照与比较工具

1. 工具简介 在日常开发、项目管理或备份场景中&#xff0c;我们经常需要知道某个文件夹中的文件是否发生变化&#xff0c;例如&#xff1a; 项目源码是否新增或修改文件&#xff1f;数据集是否被不小心删除或篡改&#xff1f;备份文件夹是否和上次一致&#xff1f; 本教程将教…

LINUX913 shell:set ip [lindex $argv 0],\r,send_user,spawn ssh root@ip “cat “

问题 获取公钥 [codesamba ~]$ cat pub.sh #!/bin/usr/expect set ip "$1" set password 123456 set timeout 20 spawn ssh root192.168.235.100:cat ~/.ssh/id_rsa.pub expect { "yes/no" {send "yes/r";exp_continue} "password:" {…

Acwing算法基础课--链表

一、单链表 AcWing 826. 单链表 代码 N 100010 idx 0 e [0] * N ne [0] * N head -1def init():global idx,headidx 0head -1def add_head(x):global idx,heade[idx] xne[idx] headhead idxidx 1def delete(k):ne[k] ne[ne[k]]def add_k(k,x):global idxe[idx] …

AI表征了西方的有界,AI+体现了东方的无界

AI表征了西方的有界&#xff0c;AI体现了东方的无界&#xff0c;试图通过文化差异的视角来对比传统AI&#xff08;AI&#xff09;与增强型或融合型AI&#xff08;AI&#xff09;的特征。一、“AI表征了西方的有界”西方的“有界”可以理解为&#xff1a;1、逻辑清晰、结构严谨&…

LabVIEW泵轮检测

​在现代制造业蓬勃发展的浪潮下&#xff0c;汽车行业也迎来了高速发展期。液力变矩器作为实现车辆自动变速的关键零件产品&#xff0c;在汽车动力系统中扮演着不可或缺的角色。泵轮作为液力变矩器的核心组成部分&#xff0c;其生产质量直接影响着液力变矩器的性能。因此&#…

RT-DETRv2 中的坐标回归机制深度解析:为什么用 `sigmoid(inv_sigmoid(ref) + delta)` 而不是除以图像尺寸?

引言&#xff1a;一个看似简单的公式&#xff0c;背后藏着工业级设计智慧 在阅读 RT-DETRv2&#xff08;Real-Time DETR v2&#xff09;源码时&#xff0c;我曾被一行代码深深震撼&#xff1a; inter_ref_bbox F.sigmoid(bbox_head[i](output) inverse_sigmoid(ref_points_de…

简单了解一下GraphRAG

传统RAG的缺点 当我们将一段文本信息以句子分割后&#xff0c;存入到向量数据库中。用户提问“老王喜欢吃什么”&#xff0c;这个问题会与向量数据库中的许多句子关联性比较强&#xff0c;能返回准确且具体的信息。 但是&#xff0c;若是问题换成“出现了几次西瓜”&#xff0c…

HTTP 状态码背后的逻辑:从请求到响应的完整流程解析(含完整流程图)

在日常的 Web 开发与 API 调试中&#xff0c;我们经常会遇到各种 HTTP 状态码 ——404 Not Found、401 Unauthorized、500 Internal Server Error... 这些数字背后并非随机出现&#xff0c;而是服务器处理请求过程中不同阶段的 "反馈信号"。理解这些状态码的触发逻辑…

Vue:下拉框多选影响行高

目录 一、 出现场景二、 解决方案 一、 出现场景 在使用el-select增加multiple属性进行多选时&#xff0c;会出现高度塌陷的情况 二、 解决方案 首先需要在el-select中增加collapse-tags属性&#xff0c;并在style中增加如下样式 方案一 <style scoped> ::v-deep .e…

如何在高通跃龙QCS6490 Arm架构上使用Windows 11 IoT企业版?

1.简介研华已将高通跃龙QCS6490 技术应用于嵌入式模块、单板电脑和AI摄像头等各种规格的嵌入式硬件中。QCS6490平台支持全面的操作系统生态系统&#xff0c;包括Windows、Ubuntu、Yocto和 Android。Windows 11 IoT企业版是微软新一代的物联网操作系统&#xff0c;具有更强的安全…

阿里云国际代理:如何利用RDS构建高可用、可扩展的数据库架构

讲下云数据库RDS案例解析&#xff0c;若在上云或用云过程中有不懂的&#xff0c;可寻云枢国际yunshuguoji助力免卡上云用云。1、RDS MySQL数据库代理支持读写分离、连接保持、就近访问、事务拆分、连接池、SSL加密等功能&#xff0c;能够降低主实例负载&#xff0c;提高实例可用…

C++之特殊类设计

文章目录前言一、 设计一个不能被拷贝的类1. C98 实现方式2. C11 实现方式二、设计一个只能在堆上创建对象的类1. 方法一&#xff1a;析构函数私有&#xff0c;提供destory接口释放资源2. 方法二&#xff1a;构造函数私有三、 设计一个只能在栈上创建对象的类1. 实现方式四、设…

TupiTube,一款免费开源的 2D 动画创作工具

TupiTube&#xff0c;一款免费开源的 2D 动画创作工具 ** ** 功能 ** &#xff1a;开源、免费的 2D 动画软件&#xff0c;界面简单&#xff0c;支持逐帧动画、剪纸动画、定格动画&#xff0c;能导入素材并导出多种视频和图片格式&#xff0c;适合儿童、学生和动画爱好者入门创作…

MoE架构训练系统设计:专家并行与门控网络优化策略

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;注册即送-H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 摘要 混合专家&#xff08;Mixture of Experts&#xf…

使用Python爬虫,selenium和requests谁更强?

py爬虫的话&#xff0c;selenium和reqeusts谁更强&#xff0c;selenium是不是能完全取代requests? 答案基本是可以的&#xff0c;selenium适合动态网页抓取&#xff0c;因为它可以控制浏览器去点击、加载网页&#xff0c;requests则比较适合静态网页采集&#xff0c;它非常轻…