LeetCode 200:岛屿数量(图的简化版之网格结构上的BFS、DFS)

图的BFS和DFS

首先让我们回顾一下图的BFS和DFS遍历。可以看到这种BFS和DFS板子适用于图形状,或者说结构已经确定,即我们遍历的时候只需要从根节点从上往下遍历即可,不用考虑这个节点有几个叶子节点,是否会遍历到空节点等边界情况的问题。

public class Graph{public HashMap<Integer,Node>nodes;//点集,第一个参数是点的编号。和Node类中的value一致。不一定是Integer类型的,要看具体的题,有的题点编号为字母。public HashSet<Edge>edges;//边集public Graph(){nodes = new HashMap<>();edges = new HashSet<>();}
}public class Node{public int value;//点的编号,不一定是Integer类型的,要看具体的题,有的题点编号为字母。public int in;//入度public int out;//出度public ArrayList<Node>nexts;//出去的边直接相连的邻居。public ArrayList<Edge>edges//出去的边public Node(int value){this.value=value;in = 0;out = 0;nexts = new ArrayList<>();edges = new ArrayList<>();}
}public class Edge{public int weight;//边上权重public Node from;public Node to;public Edge(int weight,Node from,Node to){this.weight=weight;this.from=from;this.to=to;}
}public static void bfs(Node node){if(node==null) return;Queue<Node> queue = new LinkedList<>();HashSet<Node> set = new HashSet<>();queue.add(node);set.add(node);while(!queue.isEmpty()){Node cur = queue.poll();/*  具体的处理逻辑(宽搜一般是结点入队列后再处理)*/for(Node next: cur.nexts){if(!set.contains(next)){//如果set中没有,那么说明这个next结点没有被访问过queue.add(next);//扔到队列里set.add(next);//并且标记访问}}}
}public static void dfs(Node node){if(node==null) return;Stack<Node> stack = new Stack<>();HashSet<Node> set = new HashSet<>();stack.add(node);set.add(node);/*具体的处理逻辑(深搜一般是结点入栈前就进行处理)*/while(!stack.isEmpty()){Node cur = stack.pop();for(Node next:cur.nexts){if(!set.contains(next)){stack.push(cur);//在这里需要把cur和next两个结点同时入栈是因为stack.push(next);//想在栈里保持深度搜索的路径。这次搜索相比于上一次搜索,在栈中就多了一个next结点。set.add(cur);set.add(next);/*具体的处理逻辑 */break;//之所以立马break是因为深搜每次只走一步,不像宽搜每次走一层。}}}
}

网格结构的dfs、bfs(岛屿问题)

网格结构

但是网格结构的题不一样,一般这种题不会给出图的结构或者形状,而且不会给出根节点的具体位置,那么我们由网格结构构造图结构也比较麻烦。
首先让我们了解一下什么是网格结构。以下内容来自于力扣用户:nettee

网格结构是由 m×n个小方格组成一个网格,每个小方格与其上下左右四个方格认为是相邻的,要在这样的网格上进行某种搜索。
在这里插入图片描述
网格结构要比二叉树结构稍微复杂一些,它其实是一种简化版的图结构。

网格结构的dfs

要写好网格上的 DFS 遍历,我们首先要理解二叉树上的 DFS 遍历方法,再类比写出网格结构上的 DFS 遍历。我们写的二叉树 DFS 遍历一般是这样的:

void traverse(TreeNode root) {// 判断边界情况if (root == null) {return;}// 访问两个相邻结点:左子结点、右子结点traverse(root.left);traverse(root.right);
}

可以看到,二叉树的 DFS 有两个要素:「访问相邻结点」和「判断边界情况」。
对于网格上的 DFS,我们完全可以参考二叉树的 DFS,写出网格 DFS 的两个要素:

首先,网格结构中的格子有多少相邻结点?答案是上下左右四个。对于格子 (r, c) 来说(r 和 c 分别代表行坐标和列坐标),四个相邻的格子分别是 (r-1, c)、(r+1, c)、(r, c-1)、(r, c+1)。换句话说,网格结构是「四叉」的。
在这里插入图片描述其次,网格 DFS 中的边界情况是什么?就是超出网格m*n的范围或者遍历到已经遍历过的节点胡总和遍历到不能遍历的点(岛屿问题中的海洋格子)。
这样,我们得到了网格 DFS 遍历的框架代码:

板子
void dfs(int[][] grid, int r, int c) {// 判断边界情况// 如果坐标 (r, c) 超出了网格范围,直接返回if (!inArea(grid, r, c)) return;if(vis[r][c]==true||grid[r][c]==0) return;// 访问上、下、左、右四个相邻结点dfs(grid, r - 1, c);dfs(grid, r + 1, c);dfs(grid, r, c - 1);dfs(grid, r, c + 1);
}// 判断坐标 (r, c) 是否在网格中
boolean inArea(int[][] grid, int r, int c) {return 0 <= r && r < grid.length && 0 <= c && c < grid[0].length;
}

其中的vis[r][c]==true的判断可以试不同的题而作改动,像是一般有固定数值的网格问题,譬如0表示海洋,1表示陆地的岛屿问题,我们就可以每遍历一个格子后修改其值为2,表示这个是已经遍历过的陆地格子。然后直接判断if(grid[r][c]!=1)这样就不需要额外的一个vis数组去存储遍历信息了。

LC 200题解

对于LC 200该题而言,代码就是

public int numIslands(char[][] grid) {int num = 0;for(int r=0;r<grid.length;r++){for(int c=0;c<grid[0].length;c++){if(grid[r][c]=='1'){//外层的话我需要找到所有陆地格子,而不只是一个陆地格子//因为可能有多个不连通子图dfs(grid,r,c);num++;}}}return num;}public void dfs(char[][] grid, int r,int c){if(!ifCouldVis(grid,r,c)) return;grid[r][c]='2';dfs(grid,r+1,c);dfs(grid,r,c+1);dfs(grid,r-1,c);dfs(grid,r,c-1);}public boolean ifCouldVis(char[][] grid, int r,int c){return r>=0&&c>=0&&r<grid.length&&c<grid[0].length&&grid[r][c]=='1';}

执行用时分布3ms,击败68.78%使用 Java 的用户。
应该暂时不用优化了。

同类型题

LC130:被围绕的区域,见本人的另一篇博客
http://t.csdnimg.cn/67a6y

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

打印文件pdf怎么转换成word文档?pdf转换工具推荐

有时候我们可能需要重用PDF文件中的文本内容&#xff0c;比如引用某些段落、复制粘贴特定文字或提取数据&#xff0c;通过将pdf文件转换成word&#xff0c;可以轻松地提取和重用其中的文本&#xff0c;节省时间和努力&#xff0c;那么pdf怎么转word呢&#xff1f;可以试试本文推…

Day4.

单链表 #include <head.h>typedef struct List{int value;struct List *pointe; }*list; list create_space() {list s(struct List *)malloc(sizeof(struct List)); //向堆区申请空间s->pointe NULL;//初始化s->value 0;return s; } list inserhead_list(lis…

STM32 定时器

目录 TIM 定时器定时中断 定时器外部时钟 PWM驱动LED呼吸灯&#xff08;OC&#xff09; PWM控制舵机 PWMA驱动直流电机 输入捕获模式测频率&#xff08;IC&#xff09; 输入捕获模式测占空比 编码器接口测速(编码器接口) TIM 通用定时器 高级定时器 定时器定时中断 Ti…

C#静态数组删除数组元素不改变数组长度 vs 动态数组删除数组元素改变数组长度

目录 一、使用的方法 1.对静态数组删除指定长度并不改变数长度的方法 &#xff08;1&#xff09;静态数组 &#xff08;2&#xff09;对静态数组删除元素不得改变其长度 2.对动态数组删除指定长度并改变数长度的方法 &#xff08;1&#xff09;动态数组 &#xff08;2&a…

vite项目配置根据不同的打包环境使用不同的请求路径VITE_BASE_URL,包括报错解决

vite环境配置可以看官方文档&#xff1a;环境变量和模式 | Vite 官方中文文档 创建环境配置文件 在项目根目录下面创建.env和.env.production文件&#xff0c;.env是开发环境使用的&#xff0c;.env.production是生产环境使用的。 .env文件&#xff1a; # 基本环境 VITE_APP…

[机缘参悟-154] :一个软件架构师对佛学的理解 -19- 宏大的佛教世界观、宇宙观,即系统架构:三千大千世界、佛土、三界、九地、二十五有、六道轮回

目录 一、什么是世界观 二、佛教的世界观 2.1 佛教的世界观的关注点 2.2 佛教世界观的核心要义 2.3 佛教的世界观 三、佛教的宇宙观&#xff1a;三千大千世界 3.1 佛教的宇宙观 3.2 三千大千世界 四、三界、九地、二十五有、六道 4.1 三界与三界之外 4.1.1 关于三界…

人工智能福利站,初识人工智能,图神经网络学习,第四课

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

WebSocket+Http实现功能加成

WebSocketHttp实现功能加成 前言 首先&#xff0c;WebSocket和HTTP是两种不同的协议&#xff0c;它们在设计和用途上有一些显著的区别。以下是它们的主要特点和区别&#xff1a; HTTP (HyperText Transfer Protocol): 请求-响应模型&#xff1a; HTTP 是基于请求-响应模型的协…

夜天之书 #95 GreptimeDB 社群观察报告

GreptimeDB 是格睿科技&#xff08;Greptime&#xff09;公司研发的一款开源时序数据库&#xff0c;其源代码[1]在 GitHub 平台公开发布。 https://github.com/GreptimeTeam/greptimedb 我从 2022 年开始知道有 GreptimeDB 这个项目。2023 年&#xff0c;我注意到他们的 Commun…

字节3面真题,LeetCode上hard难度,极具启发性题解

文章目录 &#x1f680;前言&#x1f680;LeetCode&#xff1a;41. 缺失的第一个正整数&#x1f680;思路&#x1f680;整个代码思路串一下&#x1f680;Code &#x1f680;前言 铁子们好啊&#xff01;阿辉来讲道题&#xff0c;这道题据说是23年字节3面真题&#xff0c;LeetC…

OpenShift AI - 运行欺诈检测模型和流程

《OpenShift / RHEL / DevSecOps 汇总目录》 说明&#xff1a;本文已经在 OpenShift 4.14 RHODS 2.50 的环境中验证 文章目录 准备运行环境安装 OpenShift AI 环境安装 Minio 对象存储软件创建 Data Science Project创建 Data connection创建 Workbench配置 Model server创建 …

解决“org.apache.catalina.startup.Catalina.stopServer 未配置关闭端口。通过OS信号关闭服务器。服务器未关闭“

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 问题描述 项目部署至Tomcat服务器报错&#xff1a;org.apache.catalina.startup.Catalina.stopServer 未配置关闭端口。通过OS信号关闭服务 器。服务器未关闭&#xff1b;图…

探讨CSDN等级制度:博客等级、原力等级、创作者等级

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;Vir2021GKBS &#x1f43c;本文由…

跟着pink老师前端入门教程-day21+22

5.4 常见flex布局思路 5.5 背景线性渐变 语法&#xff1a; background: linear-gradient( 起始方向 , 颜色 1, 颜色 2, ...); background: -webkit-linear-gradient(left, red , blue); background: -webkit-linear-gradient(left top, red , blue); 背景渐变必须添加浏览…

学习笔记——ENM模拟

学习笔记——ENM模拟 文章目录 前言一、文献一1. 材料与方法1.1. 大致概念1.2. 生态模型的构建1.2.1. 数据来源&#xff1a;1.2.2. 数据处理&#xff1a;1.2.3. 模型参数优化&#xff1a; 1.3. 适生情况预测1.3.1. 预测模型构建1.3.2. 适生区划分 1.4. 模型的评估与验证 2. 结果…

吉他学习:识谱,认识节奏,视唱节奏,节拍器的使用

第九课 识谱https://m.lizhiweike.com/lecture2/29362692 第十课 基础乐理&#xff08;二&#xff09;——节奏篇https://mp.csdn.net/mp_blog/creation/editor?spm1011.2124.3001.6192 第十一课 视唱节奏&#xff08;一&#xff09;https://m.lizhiweike.com/lecture2/293634…

【大模型上下文长度扩展】LongQLoRA:单GPU(V100)环境下的语言模型优化方案

LongQLoRA 核心问题子问题1: 预定义的上下文长度限制子问题2: 训练资源的需求高子问题3: 保持模型性能分析不足 LongQLoRA方法拆解子问题1: 上下文长度限制子问题2: 高GPU内存需求子问题3: 精确量化导致的性能损失分析不足效果 论文&#xff1a;https://arxiv.org/pdf/2311.048…

使用深度学习对视频进行分类

目录 加载预训练卷积网络 加载数据 将帧转换为特征向量 准备训练数据 创建 LSTM 网络 指定训练选项 训练 LSTM 网络 组合视频分类网络 使用新数据进行分类 辅助函数 此示例说明如何通过将预训练图像分类模型和 LSTM 网络相结合来创建视频分类网络。 要为视频…

Win32 SDK Gui编程系列之--创建菜单

菜单的概要在“Windows编程的基础”中提到了。在这里,对菜单的制作进行更详细的说明。 1.菜单的制作 菜单将数据设置在下面的MENUITEM结构中,用InsertMenuItem函数创建。 typedef struct tagMENUITEMINFO { fMask UINT cbSize;…

第十三、十四个知识点:用javascript获取表单的内容并加密

我们先来写一段代码&#xff1a; <body><form action"#" method"post">//写一个表单<span>用户名&#xff1a;</span><input type"text" id"username" name"username"><span>密码&a…