代码随想录算法训练营第五十四天|99.岛屿数量 深搜、广搜、100.岛屿的最大面积

99.岛屿数量

在这里插入图片描述

题目链接:99.岛屿数量
文档讲解:代码随想录
状态:不会

深搜

思路:

  1. 遍历网格,发现岛屿:我们需要遍历整个二维网格,检查每一个位置上的元素。如果在遍历过程中遇到陆地(值为1),这意味着我们发现了一个新的岛屿。
  2. 深度优先搜索,标记整个岛屿:为了标记整个岛屿,我们从这个陆地开始,使用深度优先搜索(DFS)将与之相连的所有陆地都标记为已访问过。这样可以确保同一个岛屿的所有部分都被访问到,不会重复计数。
  3. 统计岛屿数量:每当完成一次DFS遍历,就表示已经标记完一个完整的岛屿,所以岛屿数量加1。
  4. 继续遍历:继续遍历网格中的下一个位置,直到所有位置都被检查过。

题解:

public class Main {/*** 计算岛屿的数量** @param grid 输入的二维网格* @return 岛屿的数量*/public static int getNum(int[][] grid) {int count = 0; // 初始化岛屿数量为0int n = grid.length; // 网格的行数int m = grid[0].length; // 网格的列数for (int i = 0; i < n; i++) { // 遍历每一行for (int j = 0; j < m; j++) { // 遍历每一列if (grid[i][j] == 1) { // 如果当前位置是陆地dfs(grid, i, j); // 进行深度优先搜索,将连接的所有陆地标记count++; // 每标记完一个岛屿,岛屿数量加1}}}return count; // 返回岛屿数量}/*** 深度优先搜索(DFS)函数,用于标记连接的所有陆地** @param grid 网格* @param x    当前行* @param y    当前列*/public static void dfs(int[][] grid, int x, int y) {if (!inArea(grid, x, y)) { // 如果坐标不在网格范围内,直接返回return;}if (grid[x][y] != 1) { // 如果当前位置不是陆地(已经是水或者已经标记过),直接返回return;}grid[x][y] = 2; // 将当前陆地标记为2,表示已访问// 对当前陆地的上下左右四个方向进行递归搜索dfs(grid, x - 1, y);dfs(grid, x + 1, y);dfs(grid, x, y - 1);dfs(grid, x, y + 1);}/*** 判断坐标 (x, y) 是否在网格中** @param grid 网格* @param x    行坐标* @param y    列坐标* @return 坐标 (x, y) 是否在网格中*/static boolean inArea(int[][] grid, int x, int y) {return 0 <= x && x < grid.length && 0 <= y && y < grid[0].length;}/*** 主函数,读取输入并输出岛屿数量** @param args 命令行参数*/public static void main(String[] args) {Scanner scanner = new Scanner(System.in); // 创建扫描器用于读取输入int n = scanner.nextInt(); // 读取网格的行数int m = scanner.nextInt(); // 读取网格的列数int[][] graph = new int[n][m]; // 创建网格// 读取网格中的每一个元素for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {graph[i][j] = scanner.nextInt();}}// 输出岛屿的数量System.out.println(getNum(graph));}
}

广搜

思路:
使用 BFS 进行遍历,从每个未访问过的陆地开始,进行岛屿的搜索。
使用一个队列来存储待处理的陆地节点,并使用一个二维数组来标记已访问过的节点,以避免重复计数。

  1. 初始化:定义方向数组,包括上、下、左、右四个方向的移动。使用队列存储起始节点,并将起始节点标记为已访问。
  2. BFS遍历:从队列中取出节点,检查其四个相邻方向的节点:
    • 如果相邻节点是未访问过的陆地(值为 1),则将其加入队列并标记为已访问。
    • 继续该过程直到队列为空,表示一个完整的岛屿已经被遍历完毕。
  3. 计数:每当从主函数的双重循环中发现未访问的陆地(即值为 1 的格子),则调用 BFS 进行扩展,并将岛屿计数加一。

题解:

  /*** 使用BFS计算岛屿数量** @param grid    输入的二维网格* @param visited 访问标记数组* @param x       当前节点行坐标* @param y       当前节点列坐标*/static void bfs(int[][] grid, boolean[][] visited, int x, int y) {int n = grid.length;int m = grid[0].length;// 方向数组:下、右、上、左int[][] dir = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};Deque<int[]> deque = new LinkedList<>();deque.addLast(new int[]{x, y}); // 将起始节点加入队列visited[x][y] = true; // 标记起始节点为已访问while (!deque.isEmpty()) {int[] point = deque.pollFirst(); // 取出队列首个节点int curX = point[0];int curY = point[1];// 遍历当前节点的四个方向for (int i = 0; i < 4; i++) {int newX = curX + dir[i][0];int newY = curY + dir[i][1];// 检查新位置是否在网格范围内,并且是未访问的陆地if (newX >= 0 && newX < n && newY >= 0 && newY < m && grid[newX][newY] == 1 && !visited[newX][newY]) {deque.addLast(new int[]{newX, newY}); // 将新位置加入队列visited[newX][newY] = true; // 标记新位置为已访问}}}}/*** 主函数,读取输入并输出岛屿数量** @param args 命令行参数*/public static void main(String[] args) {Scanner scanner = new Scanner(System.in); // 创建扫描器用于读取输入int n = scanner.nextInt(); // 读取网格的行数int m = scanner.nextInt(); // 读取网格的列数int[][] graph = new int[n][m]; // 创建网格// 读取网格中的每一个元素for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {graph[i][j] = scanner.nextInt();}}boolean[][] visited = new boolean[n][m];int count = 0;// 遍历每个位置,如果是未访问过的陆地(值为1),则调用bfs进行岛屿扩展,并计数for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (graph[i][j] == 1 && !visited[i][j]) {bfs(graph, visited, i, j); // 对未访问过的陆地进行BFS搜索count++; // 计数岛屿数量}}}// 输出岛屿的数量
//        System.out.println(getNum(graph));System.out.println(count);}

100.岛屿的最大面积

在这里插入图片描述

题目链接:100.岛屿的最大面积
文档讲解:代码随想录
状态:磕磕绊绊做出来了

思路:
在上一题的基础上,每遍历陆地中的一个格子,面积加一,返回最大面积。

dfs题解:

public class Main {// 定义方向数组,表示右、下、左、上四个方向public static int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};/*** 深度优先搜索 (DFS) 方法,计算从 (x, y) 开始的岛屿面积** @param grid    二维数组表示的网格* @param visited 二维数组标记是否访问过* @param x       当前坐标的 x 轴位置* @param y       当前坐标的 y 轴位置* @return 从 (x, y) 开始的岛屿面积*/public static int dfs(int[][] grid, boolean[][] visited, int x, int y) {// 检查是否越界、是否已经访问过、是否是水域if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || visited[x][y] || grid[x][y] == 0) {return 0;}// 将当前格子标记为已访问,并将其面积记为 1int sum = 1;visited[x][y] = true;// 遍历四个方向,并递归搜索相邻格子for (int i = 0; i < 4; i++) {int newX = x + dir[i][0];int newY = y + dir[i][1];sum += dfs(grid, visited, newX, newY);}return sum;}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 读取网格的行数和列数int n = scanner.nextInt();int m = scanner.nextInt();// 初始化网格并读取值int[][] grid = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {grid[i][j] = scanner.nextInt();}}// 初始化访问标记数组boolean[][] visited = new boolean[n][m];int maxArea = 0;// 遍历网格中的每一个格子for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {// 如果当前格子是岛屿且未被访问过,则计算从该格子开始的岛屿面积if (!visited[i][j] && grid[i][j] == 1) {maxArea = Math.max(maxArea, dfs(grid, visited, i, j));}}}// 输出最大的岛屿面积System.out.println(maxArea);}
}

bfs题解:

 public static int bfs(int[][] grid) {// 使用双端队列来存储待访问的节点Deque<int[]> deque = new LinkedList<>();// 获取网格的行数和列数int n = grid.length;int m = grid[0].length;// 用于记录最大的岛屿面积int maxArea = 0;// 遍历网格中的每一个格子for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {// 如果格子中的值为1,表示这是一个岛屿的一部分if (grid[i][j] == 1) {// 初始化当前岛屿的面积int sum = 1;// 将当前格子标记为已访问grid[i][j] = 2;// 将当前格子的坐标加入队列deque.addLast(new int[]{i, j});// 进行广度优先搜索while (!deque.isEmpty()) {// 从队列中取出一个格子的坐标int[] point = deque.pollFirst();int x = point[0];int y = point[1];// 遍历该格子周围的四个方向for (int k = 0; k < 4; k++) {int newX = x + dir[k][0];int newY = y + dir[k][1];// 检查新的坐标是否在网格范围内,并且该格子是否未被访问过if (newX >= 0 && newX < n && newY >= 0 && newY < m && grid[newX][newY] == 1) {// 将新的格子标记为已访问grid[newX][newY] = 2;// 将新的格子的坐标加入队列deque.addLast(new int[]{newX, newY});// 增加当前岛屿的面积sum++;}}}// 更新最大的岛屿面积maxArea = Math.max(maxArea, sum);}}}// 返回最大的岛屿面积return maxArea;}

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

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

相关文章

计网(1.1~1.4)

1.1计算机网络在信息时代的作用 21世纪的重要特征数字化、网络化和信息化 有三类网络&#xff1a;电信网络、有线电视网络和计算机网络 互联网两个重要基本特点&#xff0c;即连通性和共享 1.2因特网概述 &#xff08;1&#xff09;网络、互联网和互连网 网络:由若干结点和连接…

企业全历史行为数据 让你对竞争对手的一切清清楚楚

关于商业竞争&#xff0c;在刚进入信息时代的那些年&#xff0c;人们说“现代商战就是信息战”&#xff0c;强调用非对称的或者更快获得的信息来赢得竞争&#xff1b;近些年进入大数据时代&#xff0c;人们又说“得数据者得天下”&#xff0c;发现“数据算法”有很多妙用&#…

2024 Q1:AVP时代下全球XR头显市场动态与展望

随着苹果Vision Pro&#xff08;AVP&#xff09;的发布&#xff0c;空间计算时代正式拉开序幕&#xff0c;全球扩展现实&#xff08;XR&#xff09;产业迎来新的发展机遇与挑战。尽管苹果的加入激发了市场活力&#xff0c;但2024年第一季度的XR头显市场却呈现出复杂多变的格局&…

压缩视频的最佳方法,视频压縮大小不影响画质

在数字媒体时代&#xff0c;视频已成为我们记录生活和传递信息的重要方式。但随着视频分辨率的提升和拍摄时长的增加&#xff0c;视频文件的大小也随之“膨胀”。大视频文件不仅占用大量存储空间&#xff0c;还在分享和传输过程中造成不便。如何在保证画质的前提下&#xff0c;…

《基于 LatentFactor + Redis + ES 实现动态药房分配方法》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; 近期刚转战 CSDN&#xff0c;会严格把控文章质量&#xff0c;绝不滥竽充数&#xff0c;欢迎多多交流。&am…

LabVIEW液压数据采集测试系统

液压系统是装载机的重要组成部分&#xff0c;通过液压传动和控制实现各项作业功能&#xff0c;如提升、倾斜、转向等。液压系统的性能直接影响装载机的作业效率和稳定性。为了保证装载机液压系统的正常运行和优化设计&#xff0c;需要对其进行数据采集和测试。本文介绍了一套基…

vue学习day09-自定义指令、插槽

29、自定义指令 &#xff08;1&#xff09;概念&#xff1a;自己定义的指令&#xff0c;可以封装一些dom操作&#xff0c;扩展额外的功能。 &#xff08;2&#xff09;分类&#xff1a; 1&#xff09;全局注册 2&#xff09;局部注册 3&#xff09;示例&#xff1a; 让表…

gorm多表联合查询 Joins方法 LEFT JOIN , RIGHT JOIN , INNER JOIN, FULL JOIN 使用总结

gorm中多表联合查询&#xff0c;我们可以使用Joins来完成&#xff0c;这个Joins方法很灵活&#xff0c;我们可以非常方便的多多表进行联合查询&#xff0c; 我们先来看看这个方法的官方定义和使用示例&#xff1a; Joins方法定义和使用示例 当然我们这里要说的使用方式是官方示…

CUDA编程 - clock 学习记录

clock 学习记录 一、完整代码二、核函数流程三、main 函数流程四、学习总结&#xff08;共享内存的声明和使用&#xff09;&#xff1a;4.1、例子4.2、数据从全局内存复制到共享内存&#xff1a; 该程序利用CUDA并行计算能力&#xff0c;执行归约操作以找到每个块内的最小值&am…

Spark项目通用开发框架

文章目录 1. 大数据项目结构2. 类说明2.1 公共接口类2.2 TaskNameEnum指定每个任务的名称2.3 TaskRunner中编写任务的业务逻辑 3. 任务执行脚本 每个公司内部都有一套自己的架子&#xff0c;一般新人来了就直接在已有的架子上开发业务。 以下仅仅作为记录下自己使用的架子&…

16_网络IPC1-套接字描述符

用户数据报协议(UDP) 与 传输控制协议(TCP) 文件描述符函数使用套接字的行为 禁止套接字IO

vue 自定义滚动条同步拖动(移动端)

实现效果&#xff0c;拖动左右箭头实现图片区域同步滚动&#xff0c;到边缘停止拖动。 HTML代码 <template><div touchstart"onClick"><!--使用draggable组件 图片列表区域--><draggablev-model"select_list"end"onEnd"cl…

[Windows] 无需PS基础也香 Inpaint v10.2高级便携版

描述 对于经常在互联网上进行操作的学生&#xff0c;白领等&#xff01; 一款好用的软件总是能得心应手&#xff0c;事半功倍。 今天给大家带了一款高科技软件 Inpaint v10.2高级便携版 无需额外付费&#xff0c;永久免费&#xff01; 亲测可运行&#xff01;&#xff01; 内容…

AV1 编码标准中帧内预测技术概述

AV1 编码标准帧内预测 AV1&#xff08;AOMedia Video 1&#xff09;是一种开源的视频编码格式&#xff0c;旨在提供比现有标准更高的压缩效率和更好的视频质量。在帧内预测方面&#xff0c;AV1相较于其前身VP9和其他编解码标准&#xff0c;如H.264/AVC和H.265/HEVC&#xff0c;…

EMR 集群时钟同步问题及解决方案An error occurred (InvalidSignatureException)

目录 1. 问题描述2. 问题原因3. 解决过程4. 时钟同步的重要性5. Linux 系统中的时钟同步方式6. 检查 Linux 系统时钟同步状态7. EMR 集群中的时钟同步配置8. 时钟同步对大数据组件的影响9. 监控和告警策略10. 故障排除和最佳实践11. 自动化时钟同步管理12. 时钟同步与数据一致性…

C++20中的constinit说明符

constinit说明符断言(assert)变量具有静态初始化&#xff0c;即零初始化和常量初始化(zero initialization and constant initialization)&#xff0c;否则程序格式不正确(program is ill-formed)。 constinit说明符声明具有静态或线程存储持续时间(thread storage duration)的…

机器人及其相关工科专业课程体系

机器人及其相关工科专业课程体系 前言传统工科专业机械工程自动化/控制工程计算机科学与技术 新兴工科专业智能制造人工智能机器人工程 总结Reference: 前言 机器人工程专业是一个多领域交叉的前沿学科&#xff0c;涉及自然科学、工程技术、社会科学、人文科学等相关学科的理论…

ozon俄罗斯ceo丨ozon平台数据分析选品神器

ozon俄罗斯ceo是玛依妮加文特。‌作为俄罗斯最大的电子商务公司Ozon Holdings的女首席执行官&#xff0c;‌玛依妮加文特被称为俄罗斯的杰夫贝索斯&#xff08;‌亚马逊CEO&#xff09;‌。‌她在公司中发挥着重要作用&#xff0c;‌不仅负责公司的日常运营和管理&#xff0c;‌…

修改表格颜色

el-table修改表头、列的背景颜色、字体样式_el-table-column背景颜色-CSDN博客 设置表头背景颜色&#xff0c;字体 <el-table :header-cell-style"rowClass" border :data"tableDataTwo" style"width: 100%"><el-table-column width&q…

2. 白盒测试

白盒测试 1. 白盒测试定义 测试软件的内部编码和基础设施&#xff0c;重点是根据预期和期望的输出检查预定义的输入。它基于应用程序的内部工作方式&#xff0c;并围绕内部结构测试。在这种类型的测试中&#xff0c;编程测试用例需要编程技巧。白盒测试的主要目标是通过软件关…