一、实战

99岛屿数量 深搜

99. 岛屿数量

本题中每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成,也就是说斜角度链接是不算的。思路是用遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上。在遇到标记过的陆地节点和海洋节点的时候直接跳过。 这样计数器就是最终岛屿的数量。

深度优先搜索有两个版本,一个是没有终止条件,一个是有终止条件

没有终止条件版本:

package org.example;//具体运行时去掉import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int m = scan.nextInt(); // 网格行数int n = scan.nextInt(); // 网格列数int[][] grid = new int[m][n]; // 存储网格数据// 输入网格for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {grid[i][j] = scan.nextInt();}}boolean[][] visited = new boolean[m][n]; // 标记是否已访问int result = 0; // 记录岛屿数量// 遍历每个格子for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {// 如果当前格子是陆地(1)且未被访问if (!visited[i][j] && grid[i][j] == 1) {result++; // 发现新岛屿visited[i][j] = true; // 标记为已访问dfs(visited, i, j, grid); // 深度优先搜索,标记整个连通区域}}}System.out.println(result); // 输出岛屿总数scan.close();}// 四个方向:右、下、上、左(x, y 增量)public static int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};/*** 从坐标 (x, y) 开始进行深度优先搜索,标记所有相连的陆地*/private static void dfs(boolean[][] visited, int x, int y, int[][] grid) {// 向四个方向扩展for (int i = 0; i < 4; i++) {int nextX = x + dir[i][0];int nextY = y + dir[i][1];// 越界检查if (nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) {continue;}// 如果下一个位置是未访问的陆地if (!visited[nextX][nextY] && grid[nextX][nextY] == 1) {visited[nextX][nextY] = true; // 标记为已访问dfs(visited, nextX, nextY, grid); // 继续递归搜索}}}
}

有终止条件版本,其实终止条件 就写在了 调用dfs的地方,如果遇到不合法的方向,直接不会去调用dfs。:

package org.example;//具体运行时去掉import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int m = scan.nextInt(); // 网格行数int n = scan.nextInt(); // 网格列数int[][] grid = new int[m][n]; // 存储网格数据// 输入网格for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {grid[i][j] = scan.nextInt();}}boolean[][] visited = new boolean[m][n]; // 标记是否已访问int result = 0; // 记录岛屿数量// 遍历每个格子for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {// 如果当前格子是陆地(1)且未被访问if (!visited[i][j] && grid[i][j] == 1) {result++; // 发现新岛屿visited[i][j] = true; // 标记为已访问dfs(visited, i, j, grid); // 深度优先搜索,标记整个连通区域}}}System.out.println(result); // 输出岛屿总数scan.close();}// 四个方向:右、下、上、左(x, y 增量)public static int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};/*** 从坐标 (x, y) 开始进行深度优先搜索,标记所有相连的陆地*/private static void dfs(boolean[][] visited, int x, int y, int[][] grid) {if (visited[x][y] || grid[x][y] == 0) return; // 终止条件:访问过的节点 或者 遇到海水visited[x][y] = true; // 标记为已访问// 向四个方向扩展for (int i = 0; i < 4; i++) {int nextX = x + dir[i][0];int nextY = y + dir[i][1];// 越界检查if (nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) {continue;}dfs(visited, nextX, nextY, grid); // 继续递归搜索}}
}

99岛屿数量 广搜

99. 岛屿数量

本题思路与深搜类似,遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上。再遇到标记过的陆地节点和海洋节点的时候直接跳过。 这样计数器就是最终岛屿的数量。

用广搜做这道题目的时候容易超时,因为已经入队列的节点因为标记的时间太晚导致重复进入队列,因此只要 加入队列就代表 走过,就需要标记,而不是从队列拿出来的时候再去标记走过

如果从队列拿出节点,再去标记这个节点走过,就会导致很多节点重复加入队列
//超时写法
int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向
void bfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y) {queue<pair<int, int>> que;que.push({x, y});// 应在放入队列的时候就进行标记while(!que.empty()) {pair<int ,int> cur = que.front(); que.pop();int curx = cur.first;int cury = cur.second;visited[curx][cury] = true; // 从队列中取出在标记走过for (int i = 0; i < 4; i++) {int nextx = curx + dir[i][0];int nexty = cury + dir[i][1];if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;  // 越界了,直接跳过if (!visited[nextx][nexty] && grid[nextx][nexty] == '1') {que.push({nextx, nexty});}}}}

具体代码如下:

package org.example;//具体运行时去掉import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int m = scan.nextInt(); // 网格行数int n = scan.nextInt(); // 网格列数int[][] grid = new int[m][n]; // 存储网格数据// 输入网格for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {grid[i][j] = scan.nextInt();}}boolean[][] visited = new boolean[m][n]; // 标记是否已访问int result = 0; // 记录岛屿数量// 遍历每个格子for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {// 如果当前格子是陆地(1)且未被访问if (!visited[i][j] && grid[i][j] == 1) {result++; // 发现新岛屿visited[i][j] = true; // 标记为已访问bfs(visited, i, j, grid); // 深度优先搜索,标记整个连通区域}}}System.out.println(result); // 输出岛屿总数scan.close();}/*** 自定义 Pair 类,用于封装坐标 (x, y)*/static class pair {int first;int second;public pair(int first, int second) {this.first = first;this.second = second;}}// 四个方向:右、下、上、左(x, y 增量)public static int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};private static void bfs(boolean[][] visited, int x, int y, int[][] grid) {Queue<pair> queue = new LinkedList<pair>();//定义坐标队列,没有现成的pair类,在下面自定义了queue.add(new pair(x, y));visited[x][y] = true;//遇到入队直接标记为优先,// 否则出队时才标记的话会导致重复访问,比如下方节点会在右下顺序的时候被第二次访问入队while (!queue.isEmpty()) {int curX = queue.peek().first;int curY = queue.poll().second;//当前横纵坐标for (int i = 0; i < 4; i++) {//顺时针遍历新节点next,下面记录坐标int nextX = curX + dir[i][0];int nextY = curY + dir[i][1];if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length) {continue;}//去除越界部分if (!visited[nextX][nextY] && grid[nextX][nextY] == 1) {queue.add(new pair(nextX, nextY));visited[nextX][nextY] = true;//逻辑同上}}}}/*** 从坐标 (x, y) 开始进行深度优先搜索,标记所有相连的陆地*/private static void dfs(boolean[][] visited, int x, int y, int[][] grid) {if (visited[x][y] || grid[x][y] == 0) return; // 终止条件:访问过的节点 或者 遇到海水visited[x][y] = true; // 标记为已访问// 向四个方向扩展for (int i = 0; i < 4; i++) {int nextX = x + dir[i][0];int nextY = y + dir[i][1];// 越界检查if (nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) {continue;}dfs(visited, nextX, nextY, grid); // 继续递归搜索}}
}

100岛屿的最大面积(深搜-无结束条件版本)

100. 岛屿的最大面积

思路:如果是有结束条件版本,dfs处理当前节点,即在主函数遇到岛屿就计数为0,dfs处理接下来的全部陆地;如果是无结束条件版本,则dfs处理当前节点的相邻节点,即在主函数遇到岛屿就计数为1,dfs处理接下来的相邻陆地

import java.util.*;
import java.math.*;public class Main {// 四个方向:右、下、左、上(顺时针)static final int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};static int result = 0; // 记录最大岛屿面积static int count = 0;  // 记录当前岛屿的面积(DFS过程中累加)public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt(); // 网格行数int m = scanner.nextInt(); // 网格列数int[][] map = new int[n][m]; // 存储地图// 输入地图数据for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {map[i][j] = scanner.nextInt();}}boolean[][] visited = new boolean[n][m]; // 标记是否已访问// 遍历每个格子for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {// 发现未访问的陆地,开始新岛屿的DFSif (!visited[i][j] && map[i][j] == 1) {count = 0; // 重置当前岛屿面积计数器dfs(map, visited, i, j); // 深度优先搜索,统计该岛屿面积result = Math.max(count, result); // 更新最大面积}}}System.out.println(result); // 输出最大岛屿面积scanner.close();}/*** DFS:从 (x, y) 开始遍历整个连通的陆地,累加面积*/static void dfs(int[][] map, boolean[][] visited, int x, int y) {count++; // 当前格子是陆地,面积+1visited[x][y] = true; // 标记为已访问,防止重复计算// 向四个方向扩展for (int i = 0; i < 4; i++) {int nextX = x + dir[i][0];int nextY = y + dir[i][1];// 跳过:越界、已访问、海水if (nextX < 0 || nextY < 0 ||nextX >= map.length || nextY >= map[0].length ||visited[nextX][nextY] || map[nextX][nextY] == 0) {continue;}// 递归访问相邻陆地dfs(map, visited, nextX, nextY);}}
}

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

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

相关文章

读取数据excel

import pandas as pd from datetime import datetimedef generate_questions():excel_path df pd.read_excel(excel_path)theme []time_list []tag1 []tag2 []tag3 []word_count 800questions []for index, row in df.iterrows():if isinstance(row[时间], datetime):…

前端环境安装

1.vsCode 下载链接&#xff1a;Visual Studio Code - Code Editing. Redefined 添加一个wiz code扩展&#xff08;提示你需要升级的依赖&#xff09; wiz code 使用方法 效果 2.git 下载链接&#xff1a;Git - Downloads 先下载 Homebrew&#xff08;https://brew.sh/ &a…

零基础学Java第十八讲---抽象类和接口(3)

续接上一讲 目录 一、内部类 1、内部类的分类 2、静态内部类 3、实例内部类---未被static修饰的成员内部类 4、局部内部类 5、匿名内部类 二、Object类 1、获取对象信息 2、equals方法 3、hashcode方法 一、内部类 当⼀个事物的内部&#xff0c;还有⼀个部分需要⼀个…

字节数据流

记录 干货&#xff5c;8000字长文&#xff0c;深度介绍Flink在字节跳动数据流的实践 字节跳动基于Flink的MQ-Hive实时数据集成

Vision Master的C#脚本与opencv联合编程

需要在VM的C#脚本设置string类型Out变量和float类型OutF变量&#xff0c;python的输出信息会在Out变量显示 using System; using System.IO; using Script.Methods; using System.Diagnostics; using System.Net.Sockets; using System.Text; using System.Threading;public pa…

运维工作架构流程搭建

前言 在解决了运维是干什么的&#xff0c;运维的工作的意义后&#xff0c;这一章我们系统性的讲讲运维工作流程搭建&#xff0c;希望大家能通过我的分享有所收获&#xff0c;这一章干货满满。 一、网络服务器架构 按照一般的访问方式&#xff0c;按照我自己的理解画了一个网络服…

安全存储之 SAES+HUK 使用技巧和常见问题 LAT1543

关键字&#xff1a;AES&#xff0c;SAES, HUK, DHUK, 安全存储 引言 近年来&#xff0c;嵌入式设备信息安全被越来越多地提及&#xff0c;从智能穿戴产品、智能工业设备到物联网产品都对设备信息安全提出了要求&#xff0c;比如基础的安全启动&#xff0c;安全升级&#xff0…

ubuntu 20.04 搭建多用户远程桌面共享及同时在线使用

使用效果: 物理机: 远程桌面用户: 实现过程: 1.使用脚本安装xrdp并修改配置及启动服务 setup_xrdp.sh sudo apt update sudo apt install xrdp -ysudo systemctl enable xrdp sudo systemctl start xrdp#sudo vim /etc/xrdp/startwm.sh #unset DBUS_SESSION_BUS_ADDRES…

[激光原理与应用-287]:理论 - 波动光学 - 电磁波既能承载能量,又能承载信息?

电磁波既能承载能量&#xff0c;又能承载信息&#xff0c;这一特性源于其物理本质和调制技术的结合。以下从能量承载和信息承载两方面进行详细解析&#xff1a;一、电磁波如何承载能量&#xff1f;电磁波的能量承载源于其电场和磁场的周期性振荡&#xff0c;具体机制如下&#…

哪里找最新AI工具官网?如何快速对比ChatGPT替代品?AI工具导航指南 - AIbase

你是否曾有这样的经历&#xff1a; 听闻某款新AI工具爆火&#xff0c;翻遍网络却找不到可靠官网或真实评测&#xff1f; 面对功能相似的ChatGPT替代品&#xff0c;参数对比表格散落各处&#xff0c;决策耗时耗力&#xff1f; 想紧跟AI领域突破&#xff0c;却淹没在海量资讯碎…

第一阶段C#基础-15:面向对象梳理

面向对象对象三&#xff08;四&#xff09;大特征&#xff1a;封装&#xff0c;继承&#xff0c;多态&#xff0c;&#xff08;抽象&#xff09;1_封装&#xff08;1&#xff09;封装是指将数据&#xff08;属性&#xff09;和行为&#xff08;方法&#xff09;组合在一个类中&…

中国星网发展情况全面分析

中国星网作为我国卫星互联网领域的"国家队"先锋,自2021年4月成立以来已取得显著进展。截至2025年8月,中国星网主导的GW星座已累计发射73颗卫星,形成"四天两发"的高频发射节奏,标志着我国低轨卫星互联网建设进入加速期。在战略定位上,中国星网不仅承担…

C++ Qt 成员对象初始化与 TCP 长连接问题深度解析

文章目录C Qt 成员对象初始化与 TCP 长连接问题深度解析1. 栈对象、堆对象与类成员对象的区别1.1 栈对象&#xff08;局部变量&#xff09;1.2 堆对象&#xff08;动态分配&#xff09;1.3 类成员对象1.4 栈对象 vs 成员对象 vs 堆对象对比表2. 为什么初始化列表必须用2.1 构造…

深度学习周报(8.11~8.17)

目录 摘要 Abstract 1 CNN--卷积神经网络简介 2 CNN核心操作 2.1 卷积 2.2 池化 3 总结 摘要 本周主要学习了卷积神经网络&#xff08;CNN&#xff09;的相关知识&#xff0c;包括概念、基本架构与应用领域等知识&#xff0c;了解了CNN利用其结构高效地从图像等网格化数…

oracle dg duplicate限速

一些客户在搭建dg的时候需要进行限速&#xff0c;不然对生产库的影响比较大&#xff0c;例如将速度限制到200M每秒&#xff0c;语法如下&#xff1a;rman target sys/XXXX auxiliary sys/XXXXdg <<EOF run{ allocate channel d1 type disk rate 200M; allocate auxiliar…

飞算JavaAI智慧校园场景实践:从校园管理到师生服务的全链路技术革新

目录一、智慧校园核心场景的技术突破1.1 智能校园综合管理系统1.2 智慧教学资源共享系统1.3 校园生活服务集成系统二、智慧校园系统效能升级实践结语&#xff1a;重新定义智慧校园技术边界在校园管理领域&#xff0c;“规模化运营”与“个性化服务”的矛盾、“管理效率”与“服…

PTPX分析中,如何处理fsdb文件过大的问题?

PTPX分析中&#xff0c;如何处理fsdb文件过大的问题&#xff1f;摘要&#xff1a;下面将基于Synopsys工具链&#xff08;PrimeTime PX&#xff0c;即PTPX&#xff0c;用于功耗分析&#xff1b;Verdi&#xff0c;用于波形查看&#xff09;逐一解答每个部分。这些工具在SoC功耗验…

004.Redis 数据持久化概述及实战

文章目录Redis持久化说明Redis持久化RDB持久化AOF持久化混合持久化save与bgsaveRedis RDB持久化Redis 安装Redis RDB配置手动触发RDB持久化模拟写入测试数据模拟进程异常RDB的优缺点优势劣势Redis AOF持久化Redis 安装Redis AOF配置AOF持久化模拟写入测试数据模拟进程异常AOF的…

Kubernetes(K8s)常用命令全解析:从基础到进阶

Kubernetes&#xff08;K8s&#xff09;常用命令全解析&#xff1a;从基础到进阶 引言&#xff1a;为什么掌握K8s命令是云原生时代的必备技能&#xff1f; Kubernetes&#xff08;简称K8s&#xff09;作为容器编排的事实标准&#xff0c;已成为云原生应用部署、扩展和管理的核…

深入解析StatefulSet与K8s服务管理

目录 一、Statefulset控制器&#xff1a;概念、原理解读 有状态服务 无状态服务 StatefulSet部分组成 Headless service 二、Statefulset资源清单文件编写技巧 三、Statefulset使用案例&#xff1a;部署web站点 四、Statefulset管理pod&#xff1a;扩容、缩容、更新 St…