当前位置: 首页 > news >正文

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函数中,需要检查下一个位置是否越界。如果越界,直接跳过。
示例代码中已经包含了越界检查:

总结

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

明天继续加油!

道阻且长,行则将至。

相关文章:

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

语言 Java 99.岛屿数量 深搜 广搜 99. 岛屿数量 题目 题目描述 给定一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的矩阵&#xff0c;你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成&#xff0c;并且四周都是水域。你可…...

css之grid布局(网格布局)

简述&#xff1a; 网格布局顾名思义就是将元素呈现为网状的整齐布局 简单使用&#xff1a; <div><div class"test"><div class"item">1</div><div class"item">2</div><div class"item">…...

数据可视化大屏模板-美化图表

Axure作为一款强大的原型设计软件&#xff0c;不仅擅长构建交互式界面&#xff0c;更在数据可视化方面展现出了非凡的创意与实用性。今天&#xff0c;就让我们一起探索Axure设计的几款精美数据可视化大屏模板&#xff0c;感受数据之美。 立体图表的视觉冲击力 Axure的数据可视…...

【与C++的邂逅】--- 类和对象(中)

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 与C的邂逅 本篇博客我们将学习类和对象中&#xff0c;认识类的六个默认成员函数以及实现日期类。下图为本节思维导图。 &#x1f3e0; 类的6个默认成员函…...

[数据集][目标检测]瞳孔虹膜检测数据集VOC+YOLO格式8768张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;8768 标注数量(xml文件个数)&#xff1a;8768 标注数量(txt文件个数)&#xff1a;8768 标注…...

Day42 | 739. 每日温度 496.下一个更大元素 I 503.下一个更大元素II

语言 Java 739. 每日温度 每日温度 题目 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该…...

运维大规模K8S集群注意事项

序言 闲来无事&#xff0c;一片混沌&#xff0c;想不清思不断&#xff0c;改变好像来自于各个方面&#xff0c;有的时候是内部的冲突&#xff0c;有的时候是外部的竞争&#xff0c;然而&#xff0c;大部分情况下&#xff0c;一旦错过&#xff0c;就已经没得选了。 尴尬的处境&a…...

供应链系统源码的关键技术是什么?

供应链管理是企业运营中的重要环节&#xff0c;而高效的供应链系统能够大幅提升企业的竞争力。在数字化转型的过程中&#xff0c;越来越多的企业选择使用开源供应链系统源码来定制开发适合自身需求的解决方案。那么&#xff0c;供应链系统源码的关键技术有哪些&#xff1f;本文…...

git 修改远程仓库的 URL

git remote set-url origin 修改远程仓库的 URL。 old:ssh://wangzhijun192.168.10.48:29418/kapok new:http://wangzhijun172.31.178.243:90/kapok git remote set-url origin ssh://wangzhijun172.31.178.243:29418/kapok old:https://120.79.152.225/wuzeyuan/flymap_app n…...

使用图数据库 Neo4j 处理对象之间的关系

使用 Neo4j 图数据库来处理明星之间的关系涉及以下主要步骤&#xff1a;数据建模、数据导入、查询和关系修改。下面是详细的操作步骤&#xff1a; 1. 安装 Neo4j 下载和安装: 从 Neo4j 官方网站 下载 Neo4j Community Edition 或者 Enterprise Edition&#xff0c;安装并启动…...

使用C#的异步和依赖注入实现网络数据存储

详细解释 依赖注入&#xff08;Dependency Injection&#xff09;: ConfigureServices 方法配置了服务的依赖注入。IDataProcessor 接口与 DataProcessor 类绑定&#xff0c;IDbConnectionFactory 接口与 DbConnectionFactory 类绑定。这样在程序运行时&#xff0c;依赖注入容器…...

tomcat日志文件切割

文章目录 引言I 使用用crontab工具,定时执行任务II 通过Linux系统自带的切割工具logrotate来进行切割logrotate 简介用法结合crontab进行自定义的定时轮转操作III 基于其他日志框架进行分隔引言 tomcat 的 catalina.out 文件不会进行日志切割,当这个文件大于2G 时,会影响to…...

Python将Word文档转为PDF

使用python将word转pdf_py work转pdf-CSDN博客 掌握Python技巧&#xff1a;PDF文件的加密和水印处理-CSDN博客...

深入浅出链表

目录 1.链表的基本概念及结构 1.1基本概念 1.2结构 2.链表的分类 3.链表的实现&#xff08;循环链表增删查改实现&#xff09; 1.动态申请节点&#xff08;结点&#xff09;​编辑 2.单链表打印 3.单链表尾插 4.单链表头插 5.单链表尾删 6.单链表头删 7.单链表查找 …...

Linux核心命令入门

Linux常用命令 文件管理文件目录管理文件查看编辑 系统管理网络管理hostnamehost/nslookuptraceroutenetstat列出所有端口 (包括监听和未监听的)列出所有处于监听状态的 Sockets显示每个协议的统计信息 硬件管理df&#xff08;Disk Free&#xff09;du&#xff08;Disk Usage&a…...

腾讯无界微前端框架介绍

一、无界微前端框架概述 无界微前端框架是由腾讯团队推出的&#xff0c;旨在解决现有微前端方案中存在的问题&#xff0c;如适配成本高、样式隔离困难、运行性能不佳、页面白屏、子应用通信复杂、子应用保活机制缺乏等。 技术实现 无界微前端的核心技术是基于Web Component…...

Linux——网络(2)

一、通信 --- 不同主机上进程间的通信 1、IP和端口号 IP&#xff1a;标识网络中的一台主机 本质上 32位的整型数据 端口号: 标识某个进程 本质上 16位的整型数据 2、udp和tcp udp的特点: 1.无连接 2.不可靠 tcp的特点&#xff1a; 1.面…...

结合量子技术解决数据传输安全

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 接前篇&#xff1a;数采网关面…...

【Rust光年纪】提高开发效率:深入了解Rust语言中的数据库客户端和文件处理库

深入探索&#xff1a;Rust语言中多款数据库客户端与文件处理库详解 前言 在现代软件开发中&#xff0c;使用各种数据库和文件处理操作是非常常见的。Rust语言作为一种快速、安全、并发的系统编程语言&#xff0c;也拥有丰富的生态系统和库。本文将介绍几个用于Rust语言的数据…...

【自动驾驶】控制算法(一)绪论与前期准备

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…...

移动端性能优化体系

移动端性能优化体系&#xff1a;打造极致用户体验 在移动互联网时代&#xff0c;用户对应用性能的要求越来越高。页面加载慢、卡顿、耗电等问题直接影响用户体验&#xff0c;甚至导致用户流失。构建一套完整的移动端性能优化体系至关重要。本文将从多个角度深入探讨移动端性能…...

别让AI代码,变成明天的技术债甭

如果有多个供应商&#xff0c;你也可以使用 [[CC-Switch]] 来可视化管理这些API key&#xff0c;以及claude code 的skills。 # 多平台安装指令 curl -fsSL https://claude.ai/install.sh | bash ## Claude Code 配置 GLM Coding Plan curl -O "https://cdn.bigmodel.cn/i…...

C# 面试高频题:装箱和拆箱是如何影响性能的?负

OCP原则 ocp指开闭原则&#xff0c;对扩展开放&#xff0c;对修改关闭。是七大原则中最基本的一个原则。 依赖倒置原则&#xff08;DIP&#xff09; 什么是依赖倒置原则 核心是面向接口编程、面向抽象编程&#xff0c; 不是面向具体编程。 依赖倒置原则的目的 降低耦合度&#…...

实战指南 | 利用FRP与TOML配置实现高效内网穿透(含反向代理优化)

1. 为什么需要内网穿透&#xff1f; 想象一下这个场景&#xff1a;你家里有一台NAS存储设备&#xff0c;里面存满了家人照片和工作文档&#xff1b;或者你在本地开发了一个网站应用&#xff0c;想临时分享给异地同事测试。这时候你会发现——从外部网络根本无法访问这些服务&am…...

基于 IndexTTS2 的数字人语音生成 Pipeline 设计

IndexTTS2 是目前情感控制与时长控制能力最强的开源自回归 TTS 模型&#xff0c;非常适合作为数字人系统的「语音生成核心模块」。 本设计旨在构建一个从输入文案到最终数字人语音/视频的完整 Pipeline&#xff0c;使数字人能够做到&#xff1a; 克隆音色表达情感按剧本中的动作…...

Taskr性能优化秘籍:从毫秒级任务到大规模项目的最佳实践

Taskr性能优化秘籍&#xff1a;从毫秒级任务到大规模项目的最佳实践 【免费下载链接】taskr A fast, concurrency-focused task automation tool. 项目地址: https://gitcode.com/gh_mirrors/ta/taskr Taskr是一款专注于并发的快速任务自动化工具&#xff0c;作为与Gulp…...

从2D照片到3D场景的终极转换:深度实战fSpy相机匹配工具

从2D照片到3D场景的终极转换&#xff1a;深度实战fSpy相机匹配工具 【免费下载链接】fSpy A cross platform app for quick and easy still image camera matching 项目地址: https://gitcode.com/gh_mirrors/fs/fSpy 你是否曾面对一张建筑照片&#xff0c;想要在3D软件…...

Android Studio移动开发入门:构想集成Phi-3-vision模型的智能相机App

Android Studio移动开发入门&#xff1a;构想集成Phi-3-vision模型的智能相机App 1. 从零开始的智能相机构想 想象这样一个场景&#xff1a;当你用手机拍摄一朵花时&#xff0c;相机不仅能自动识别花的品种&#xff0c;还能告诉你它的生长习性和养护要点&#xff1b;当你扫描…...

波普尔:反教皇的“新教皇”——一场百年认知诈骗的终极揭露

波普尔&#xff1a;反教皇的“新教皇”——一场百年认知诈骗的终极揭露摘要波普尔以“反教皇”自居&#xff0c;实则上演了最隐蔽的学术独裁。他通过偷换“绝对真理”概念&#xff0c;将确定性真理污名化为教皇式专制&#xff0c;再借“可证伪性”自封科学裁判&#xff0c;垄断…...

为什么专业编剧都在用Trelby?免费开源剧本写作软件的终极指南

为什么专业编剧都在用Trelby&#xff1f;免费开源剧本写作软件的终极指南 【免费下载链接】trelby The free, multiplatform, feature-rich screenwriting program! 项目地址: https://gitcode.com/gh_mirrors/tr/trelby 你是否曾经因为剧本格式问题而烦恼&#xff1f;是…...