Day45 | 99.岛屿数量 深搜 广搜 100.岛屿的最大面积

语言

Java

99.岛屿数量 深搜 广搜

99. 岛屿数量

题目

题目描述

给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。

输入描述

第一行包含两个整数 N, M,表示矩阵的行数和列数。

后续 N 行,每行包含 M 个数字,数字为 1 或者 0。

输出描述

输出一个整数,表示岛屿的数量。如果不存在岛屿,则输出 0。

思路(深搜版本)

第一次思路

1.创建一个二维数组
2.通过Scanner输入多少就是几乘几的二维数组,定义一个结果res

3.这时我们得到一个二维数组,遍历二维数组,找到为1的地方

4.?如何看他周围有没有1组成个大岛屿
5.如果是大岛屿res+1

6.输出res的值

最终思路

  1. 初始化
    • 读取网格的大小(行数和列数)。
    • 创建一个与网格大小相同的二维数组grid来存储输入数据。
    • 创建一个同样大小的二维布尔数组visited,用于跟踪哪些陆地(1)已经被访问过。初始时,所有位置都设为false
  2. 遍历网格
    • 使用两层嵌套循环遍历网格中的每一个位置。
    • 对于每个位置,检查它是否是陆地(grid[i][j] == 1)且尚未被访问(visited[i][j] == false)。
  3. 深度优先搜索(DFS)
    • 如果发现一个未被访问的陆地,那么我们就找到了一个新的岛屿。此时,将岛屿计数器加一。
    • 对这个陆地位置执行DFS,以标记与这个陆地相连的所有陆地(即这个岛屿的所有部分)为已访问。
    • DFS过程中,我们遍历当前陆地位置的四个相邻方向(上、下、左、右),如果相邻位置是陆地且未被访问,则递归地对该位置执行DFS。
  4. 结果输出
    • 遍历和DFS完成后,岛屿计数器的值即为网格中岛屿的总数。
    • 输出岛屿的总数。

代码

import java.util.Scanner;  public class Main {  static final int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; // 四个方向  static void dfs(int[][] grid, boolean[][] visited, int x, int y) {  for (int i = 0; i < 4; i++) {  int nextx = x + dir[i][0];  int nexty = y + dir[i][1];  if (nextx < 0 || nextx >= grid.length || nexty < 0 || nexty >= grid[0].length) continue;  // 越界了,直接跳过  if (!visited[nextx][nexty] && grid[nextx][nexty] == 1) { // 没有访问过的 同时 是陆地的  visited[nextx][nexty] = true;  dfs(grid, visited, nextx, nexty);  }  }  }  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];  boolean[][] visited = new boolean[n][m];  for (int i = 0; i < n; i++) {  for (int j = 0; j < m; j++) {  grid[i][j] = scanner.nextInt();  }  }  int result = 0;  for (int i = 0; i < n; i++) {  for (int j = 0; j < m; j++) {  if (!visited[i][j] && grid[i][j] == 1) {  visited[i][j] = true;  result++; // 遇到没访问过的陆地,+1  dfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true  }  }  }  System.out.println(result);  }  
}

易错点

  • DFS:深度优先搜索是解决此类问题的关键。它允许我们从一个陆地位置开始,探索并标记与该位置相连的所有陆地,直到没有更多的相邻陆地为止。
  • 避免重复计数:通过visited数组,我们可以确保每个岛屿只被计数一次。即使一个岛屿由多个陆地组成,DFS也会确保我们只在首次遇到岛屿时增加计数器,并标记岛屿的所有部分为已访问。
  • 边界条件:在DFS过程中,我们需要检查相邻位置是否越界(即是否仍在网格范围内内),以及相邻位置是否是陆地且未被访问

思路(广搜版本)

  1. 理解问题
    • 首先,明确问题的要求。例如,在网格中,你可能需要计算由1(代表陆地)组成的连通区域的数量。
  2. 初始化
    • 创建一个与网格大小相同的visited数组(或类似的数据结构),用于跟踪哪些位置已经被访问过。
    • 创建一个队列(如LinkedList),用于BFS的遍历。
  3. 遍历网格
    • 遍历网格的每个位置。
    • 对于每个位置,如果它是陆地(即值为1)且尚未被访问过,则将其视为一个新的连通区域。
  4. BFS遍历
    • 将当前位置加入队列,并标记为已访问。
    • 当队列不为空时,从队列中取出一个位置,并检查其四个相邻位置(上、下、左、右)。
    • 如果相邻位置是陆地且未被访问过,则将其加入队列并标记为已访问。
    • 重复此过程,直到队列为空。
  5. 计数
    • 对于每个新发现的连通区域,增加计数器。
  6. 输出结果
    • 遍历结束后,输出连通区域的数量。

代码

import java.util.LinkedList;  
import java.util.Queue;  
import java.util.Scanner;  
import java.util.Vector;  public class Main {  private static final int[][] DIRECTIONS = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; // 四个方向  public static void bfs(int[][] grid, boolean[][] visited, int x, int y) {  Queue<int[]> que = new LinkedList<>();  que.offer(new int[]{x, y});  visited[x][y] = true; // 只要加入队列,立刻标记  while (!que.isEmpty()) {  int[] cur = que.poll();  int curx = cur[0];  int cury = cur[1];  for (int i = 0; i < 4; i++) {  int nextx = curx + DIRECTIONS[i][0];  int nexty = cury + DIRECTIONS[i][1];  if (nextx < 0 || nextx >= grid.length || nexty < 0 || nexty >= grid[0].length) continue; // 越界了,直接跳过  if (!visited[nextx][nexty] && grid[nextx][nexty] == 1) {  que.offer(new int[]{nextx, nexty});  visited[nextx][nexty] = true; // 只要加入队列立刻标记  }  }  }  }  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];  boolean[][] visited = new boolean[n][m];  for (int i = 0; i < n; i++) {  for (int j = 0; j < m; j++) {  grid[i][j] = scanner.nextInt();  }  }  int result = 0;  for (int i = 0; i < n; i++) {  for (int j = 0; j < m; j++) {  if (!visited[i][j] && grid[i][j] == 1) {  result++; // 遇到没访问过的陆地,+1  bfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true  }  }  }  System.out.println(result);  }  
}

易错点

  1. 边界检查
    • 在检查相邻位置时,容易忘记检查它们是否越界(即是否在网格的范围内)。
  2. 重复访问
    • 如果没有正确地使用visited数组(或类似的数据结构),可能会导致同一个位置被多次访问,从而影响结果。

100.岛屿的最大面积

100. 岛屿的最大面积

题目

题目描述

给定一个由 1(陆地)和 0(水)组成的矩阵,计算岛屿的最大面积。岛屿面积的计算方式为组成岛屿的陆地的总数。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。

输入描述

第一行包含两个整数 N, M,表示矩阵的行数和列数。后续 N 行,每行包含 M 个数字,数字为 1 或者 0,表示岛屿的单元格。

输出描述

输出一个整数,表示岛屿的最大面积。如果不存在岛屿,则输出 0。

思路

  1. 输入读取

    • 读取网格的行数n和列数m
    • 读取网格的数据,存储在二维数组grid中。
  2. 初始化

    • 初始化一个与grid大小相同的二维布尔数组visited,用于标记每个位置是否被访问过。
  3. 遍历网格

    • 遍历整个网格,对于每个未访问的陆地(即grid[i][j] == 1!visited[i][j]),执行以下操作:
      • 初始化count为1,表示当前岛屿的大小。
      • 标记当前位置为已访问。
      • 调用DFS函数,遍历并标记所有相邻的陆地。
      • 更新最大岛屿大小result
  4. DFS函数

    • 从当前位置(x, y)出发,遍历四个方向的相邻位置。
    • 如果相邻位置越界或不是陆地或已经访问过,则跳过。
    • 否则,标记该位置为已访问,增加count,并递归调用DFS函数。
  5. 输出结果

    • 输出最大的岛屿大小result

代码

import java.util.Scanner;public class Main {private static int count;private static final int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; // 四个方向public static void dfs(int[][] grid, boolean[][] visited, int x, int y) {for (int i = 0; i < 4; i++) {int nextx = x + dir[i][0];int nexty = y + dir[i][1];if (nextx < 0 || nextx >= grid.length || nexty < 0 || nexty >= grid[0].length) continue;  // 越界了,直接跳过if (!visited[nextx][nexty] && grid[nextx][nexty] == 1) { // 没有访问过的 同时 是陆地的visited[nextx][nexty] = true;count++;dfs(grid, visited, nextx, nexty);}}}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 result = 0;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (!visited[i][j] && grid[i][j] == 1) {count = 1;  // 因为dfs处理下一个节点,所以这里遇到陆地了就先计数,dfs处理接下来的相邻陆地visited[i][j] = true;dfs(grid, visited, i, j); // 将与其链接的陆地都标记上 trueresult = Math.max(result, count);}}}System.out.println(result);}
}

易错点

数组越界:

在DFS函数中,需要检查下一个位置是否越界。如果越界,直接跳过。
示例代码中已经包含了越界检查:

总结

今天了解深搜和广搜的思路,做了模板题岛屿问题。

明天继续加油!

道阻且长,行则将至。

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

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

相关文章

【启明智显技术分享】实时操作系统RTOS核心机制与应用

在当今这个对实时性要求日益严苛的嵌入式系统时代&#xff0c;RTOS作为核心软件架构&#xff0c;正扮演着不可或缺的角色。而当我们深入探讨RTOS的广泛应用与优势时&#xff0c;不得不提到启明智显Model系列芯片以其卓越的性能、丰富的外设接口以及对RTOS系统的全面支持&#x…

Qt实现圆型控件的三种方法之子类化控件并重写paintEvent

前言 最近在研究绘制各种形状的控件&#xff0c;这里专门挑出圆形的控件进行记录&#xff0c;其它形状的也大差不差&#xff0c;会了圆形的之后其它的也类似。 正文 这里我挑出Label来进行举例。 子类化 QLabel 并重写 paintEvent 如果需要更复杂的自定义绘制&#xff0c;…

【CSS】使用 CSS 自定义属性(变量)-- var()

自定义属性&#xff08;有时候也被称作CSS 变量或者级联变量&#xff09;是由 CSS 作者定义的&#xff0c;它包含的值可以在整个文档中重复使用。由自定义属性标记设定值&#xff08;比如&#xff1a; --main-color: black;&#xff09;&#xff0c;由 var() 函数来获取值&…

算法全面剖析

算法 查找算法&#xff1a; 顺序查找&#xff1a; 基本思想&#xff1a; 顺序查找也称为线形查找&#xff0c;属于无序查找算法。从数据结构线形表的一端开始&#xff0c;顺序扫描&#xff0c;依次将扫描到的结点关键字与给定值k相比较&#xff0c;若相等则表示查找成功&am…

Nginx--监控

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、Nginx的基础监控 进程监控 端口监控 注意&#xff1a; 这两个是必须要加在zabbix监控&#xff0c;加触发器有问题及时告警。 nginx 提供了ngx…

编译linux内核时,让版本号不跟着git变化

文章目录 编译linux内核时&#xff0c;让版本号不跟着git变化现象方法一方法二 编译linux内核时&#xff0c;让版本号不跟着git变化 现象 内核每次重新编译时&#xff0c;uname -r都会跟着变。 4.1.15-00005-g482731e4-dirty 导致报错&#xff0c;modprobe: can’t change …

前端算法 | LeetCode第 70 题爬楼梯问题

目录 流程分析 归纳法分析 为什么是斐波那契数列&#xff1f; 推导过程&#xff1a; 解法1&#xff1a;循环累加计算 解法2&#xff1a;递归计算 解法3&#xff1a;利用数组特性 解法4&#xff1a;利用 JavaScript ES6 新特性 拓展知识&#xff1a;每次可以走 1 步、2…

ClickHouse实时探索与实践 京东云

1 前言 京喜达技术部在社区团购场景下采用JDQFlinkElasticsearch架构来打造实时数据报表。随着业务的发展 Elasticsearch开始暴露出一些弊端&#xff0c;不适合大批量的数据查询&#xff0c;高频次深度分页导出导致ES宕机、不能精确去重统计&#xff0c;多个字段聚合计算时性能…

位运算专题

分享丨【题单】位运算&#xff08;基础/性质/拆位/试填/恒等式/思维&#xff09; - 力扣&#xff08;LeetCode&#xff09; Leetcode 3133. 数组最后一个元素的最小值 我的答案与思路&#xff1a; class Solution { public: // 4 --> (100)2 7 --> (0111)2 // 5 --&g…

怎么让FLV转MP4?建议试试这样做

怎么让FLV转MP4&#xff1f;在数字视频处理的日常中&#xff0c;我们经常会遇到不同格式的视频文件需要相互转换的情况。FLV&#xff08;Flash Video&#xff09;作为一种早期的网络视频格式&#xff0c;虽然在互联网上仍有一定应用&#xff0c;但对比来说&#xff0c;MP4格式更…

vue打包设置 自定义的NODE_ENV

默认NODE_ENV 自定义process.env.NODE_ENV的值_process.node.env的值-CSDN博客 ‌NODE_ENV开发环境下&#xff1a;NODE_ENVdevelopment(默认) 生产环境下&#xff1a;NODE_ENVproduction(默认) NODE_ENV 除了默认的 development 和 production 以外&#xff0c;确实可以自定义…

Apache CloudStack Official Document 翻译节选(八)

关于 Apache CloudStack 的 最佳实践 &#xff08;二&#xff09; 防火墙的设定 Hardware Firewall 部署Apache CloudStack时&#xff0c;建议部署一套防火墙系统已保护Apache CloudStack的云管理服务。在防火墙的选用方面&#xff0c;既可以使用通用防火墙、也可以使用诸如Ju…

树莓派3B运行rasa init和rasa shell遇到的tensorflow报错总结

终于在我的树莓派上安装rasa-1.4.0版本成功&#xff08;见《树莓派智能语音助手之聊天机器人-RASA》&#xff09;。不过&#xff0c;在初始化rasa的时候还是遇到了很多报错&#xff0c;在此总结&#xff0c;供朋友们参考。 1. ModuleNotFoundError: No module named ‘tensorf…

【鸿蒙学习】HarmonyOS应用开发者高级认证 - 应用性能优化一(界面层面)

学完时间&#xff1a;2024年8月22日 学完排名&#xff1a;第1801名 一、介绍 在开发HarmonyOS应用时,优化应用性能是至关重要的。通过/ArkTS高性能编程、减少丢帧卡顿、提升应用启动和响应速度 可以有效提升用户体验。本文将介绍一些优化HarmonyOS应用性能的方法。 一、Ark…

Windows-Server-2016/2019绕过WindowsDefender

当获得了一个webshell的时候&#xff0c;下一步要反弹个shell回来 在尝试了https://github.com/trustedsec/unicorn独角兽失败之后&#xff0c;找到了一篇使用golang将shellcode注入到内存的文章 Bypassing Antivirus with Golang - Gopher it! | JUMPSEC LABS GitHub - brimst…

谷粒商城实战笔记-213-商城业务-认证服务-整合短信验证码服务

文章目录 一&#xff0c;开通阿里云云市场短信服务1&#xff0c;阿里云开通免费短信服务并调试2&#xff0c;整合短信服务2.1 下载HttpUtils代码2.2 开发调用短信服务的组件2.3 测试 HttpUtils代码 这一节主要内容是整合短信发送服务。 一&#xff0c;开通阿里云云市场短信服务…

Wemos D1 Mini pro/ nodeMcu / ESP8266 驱动 240*320 ILI9431 SPI液晶屏

Wemos D1 Mini / nodeMcu / ESP8266 驱动 240*320 ILI9431 SPI液晶屏 效果展示器件硬件连接引脚连接原理图引脚对照表 安装TFT_eSPI库TFT_eSPI库中User_Setup.h文件的参数修改User_Setup.h文件的位置User_Setup.h文件中需要修改的参数User_Setup.h完成源码 例程 缘起&#xff1…

【MySQL】半同步模式

1 半同步模式原理 1. 用户线程写入完成后 master 中的 dump 会把日志推送到 slave 端 2.slave 中的 io 线程接收后保存到 relaylog 中继日志 3. 保存完成后 slave 向 master 端返回 ack 4. 在未接受到 slave 的 ack 时 master 端时不做提交的&#xff0c;一直处于等待当收到…

秃姐学AI系列之:AlexNet + 代码实现

目录 深度学习之前的网络 机器学习 几何学 特征工程 总结 深度卷积神经网络的突破的两个关键因素 数据 ImageNet&#xff08;2010&#xff09; 硬件 90年&#xff1a;数据量和计算能力发展的均匀且都不大的时候——神经网络 00年&#xff1a;内存不错、算力也不错&a…

docker-compose安装NebulaGraph 3.8.0

文章目录 一. 安装NebulaGraph1.1 通过 Git 克隆nebula-docker-compose仓库的3.8.0分支到主机1.2 部署1.3 卸载1.4 查看 二. 安装NebulaGraph Studio2.1 下载 Studio 的部署配置文件2.2 创建nebula-graph-studio-3.10.0目录&#xff0c;并将安装包解压至目录中2.3 解压后进入 n…