java算法day25

java算法day25

  • 广度优先搜索
  • 岛屿数量深搜
  • 岛屿数量广搜

广度优先搜索

核心:从起点出发,以起始点为中心一圈一圈进行搜索,一旦遇到终点,记录之前走过的节点就是一条最短路。搜索的方式是上下左右
在这里插入图片描述


一张图说明白模拟过程:
在这里插入图片描述
每一层,每个点不停的往上下左右的方向扩。
在面对有障碍的情况下也同样如此:
在这里插入图片描述

所以可以得出一个结论:
因为bfs这种一圈一圈层层往外搜索的性质,决定了bfs处理得到的路径一定是一条最短路径。

那这种一圈一圈的搜索过程是怎么做到的,用了什么容器才能实现这样的遍历。
回答是:用队列,栈,数组都可以。但是这里习惯用队列。
用队列那就是保证每一圈都是一个方向去转,例如统一顺时针或者统一逆时针。
因为队列是先进先出,加入元素和弹出元素的顺序没有发生改变。
而且顺时针和逆时针转都是可以的,并不用做什么特殊处理。

接下来是一个队列的模板。看看用队列怎么完成bfs。

import java.util.*;  class Solution {  // 表示四个方向:右、下、上、左  private static final int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};  // grid 是地图,是一个二维字符数组  // visited 标记访问过的节点,避免重复访问  // x, y 表示开始搜索节点的坐标  public void bfs(char[][] grid, boolean[][] visited, int x, int y) {  //定义队列,该队列用于BFS,其中存的都是点Queue<int[]> queue = new LinkedList<>();  queue.offer(new int[]{x, y}); // 起始节点加入队列  visited[x][y] = true; // 标记起始节点为已访问  //BFS主循环,当队列不空时,继续搜索while (!queue.isEmpty()) {//从队列中把要处理的点取出来,x坐标是cur[0],y坐标是cur[1]。这里把要处理的点的坐标拿出来是为了方便等下做上下左右运算。  int[] cur = queue.poll();  int curx = cur[0];  int cury = cur[1];  // 遍历四个方向:右、下、上、左  //这里相当于处理当前节点,for (int[] d : dir) {//为了方便还是计算该节点下一步要走的坐标。分别计算横坐标和纵坐标  int nextx = curx + d[0];  int nexty = cury + d[1];  //这个点算出来了 检查是否越界,看看这个点是否合法  if (nextx < 0 || nextx >= grid.length || nexty < 0 || nexty >= grid[0].length) {//如果这里面有一个不满足就代表这个点不合法,那么就不处理,所以跳过处理该方向的点。continue;  }  //能走到这里说明点是合法的,但是还要看看这个点之前访问过了没。直接通过这个标记数组进行检查即可// 如果下一个节点没有被访问过,就会进去if (!visited[nextx][nexty]) {//然后把这个没访问的节点放入待处理的队列中  queue.offer(new int[]{nextx, nexty});//然后把该点设置为已经访问  visited[nextx][nexty] = true;  // 在这里可以根据具体问题进行额外的处理  }//到了这里就会发现,循环里的某方向的一个点处理,而且还把该节点加入到了队列里。因为之后处理这个节点,往外面的方向扩的过程就是上面模拟的bfs。//这里一个方向就已经处理完毕,下一个循环就是下一个方向了。所以依次类推,就是一圈一圈的往外处理。//以中间的这个点来模拟,左方向处理完后加入了队列,然后假设转了一圈,跳转下一个节点的时候,从队列里第一个弹出来的节点就是这个左方向的节点,他也是如此的方式进行模拟。  }  }  }  
}

我学完这个模板之后,我感觉特别像层序遍历。不过是在图的角度上。

使用这个模板的步骤:

定义问题的网格(grid)。
创建一个与网格大小相同的 visited 数组。
选择起始位置(x, y)。
调用 bfs 方法。


岛屿数量深搜

算法思想:
1、遍历整个网格
2、当找到一个未访问的陆地时,将岛屿计数+1
3、然后调用DFS标记与这个陆地相连的所有陆地为已访问(用dfs就是递归,但是还是有一点BFS的影子,直接往四个方向都递归,当遇到节点是0就停下,或者节点不合法了也停下)
4、重复这个过程直到遍历完整个网络(相当于把整个网格都处理了。)

这种方法是可以有效的计算岛屿数量,因为每个岛屿只会被计数一次,而与他相连的所有陆地都会在dfs的过程中被标记。

import java.util.Scanner; public class Main{//规定四个方向,方便用来计算四个要遍历的方向static final int[][] dir = {{0,1},{1,0},{-1,0},{0,-1}};//主方法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++){//遍历的过程中,如果遇到陆地,并且没有访问过,那就意味着这是一个新岛屿,所以先计数器++,然后dfs。把该陆地上所有相邻陆地全部标记为已经访问。if(!visited[i][j] && grid[i][j]==1){result++;//就是dfs这个第一个遇见的陆地,之后会dfs把相邻的陆地全部置为已经访问dfs(grid,visited,i,j);}}}//结果输出System.out.println(result);}public static void dfs(int[][] grid,boolean[][] visited,int x,int y){//这里我写递归出口是已经考虑了,我是遇到了第一个陆地网格才进来的//所以这里递归出口的条件就会松一点。if(visited[x][y] || grid[x][y]==0){return;}//先处理当前节点,这里要进行处理就是把他置为truevisited[x][y] = true;//然后遍历四个方向,每个方向都要进行dfsfor(int[] d:dir){//dfs之前,把要dfs的坐标算出来int nextX = x+d[0];int nextY = y+d[1];//在进行dfs之前,还要判断这个方向的节点是否合法。//不合法就跳过了。if(nextX<0 || nextX>=grid.length || nextY<0 || nextY>=grid[0].length){continue;}//合法就dfsdfs(grid,visited,nextX,nextY);}}
}

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

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

相关文章

【C语言】深入探讨数组传参

一、数组传参简介 在C语言中&#xff0c;数组传参是一个常见的操作&#xff0c;尤其是在处理大量数据或需要多次访问相同数据集时。理解如何传递数组以及这些方法之间的差异是编写高效和安全代码的关键。在这篇博客中&#xff0c;我们将详细讨论C语言中数组传参的几种常见方法&…

rhce THE homework of first

ssh远程免密登录成功 下载httpd和nginx 关闭防火墙 查看selinux的状态 为服务器配置ip 填充网站的内容 添加服务器配置

Python爬虫入门01:在Chrome浏览器轻松抓包

文章目录 爬虫基本概念爬虫定义爬虫工作原理爬虫流程爬虫类型爬虫面临的挑战 使用Chrome浏览器抓包查看网页HTML代码查看HTTP请求请求头&#xff08;Request Header&#xff09;服务器响应抓包的意义 爬虫基本概念 爬虫定义 爬虫&#xff08;Web Crawler 或 Spider&#xff0…

MongoDB教程(二十三):关于MongoDB自增机制

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、MongoD…

数字孪生在奥运会上的应用

数字孪生是一种精确的虚拟空间表示&#xff0c;能够实时模拟场馆内的各种变化或场景。国际奥委会正在确定高价值的应用案例和技术要求&#xff0c;将应用案例分为六个主要领域&#xff1a;场馆规划、利益相关者支持与参与、操作准备、粉丝体验、遗产和运营效率。每个案例将基于…

【前端 13】Vue快速入门

Vue快速入门 在现代Web开发中&#xff0c;尽管通过HTML、CSS和JavaScript我们能够构建出美观且功能丰富的页面&#xff0c;但随着项目规模的增大&#xff0c;这种传统的开发方式在效率上逐渐显得力不从心。为了提高开发效率&#xff0c;前端开发者们引入了多种框架和库&#x…

MySQL环境的配置文件json

突然了解到&#xff0c;使用json文件去进行环境的配置&#xff0c;这样修改参数的时候就只需要去改json文件中的内容&#xff0c;不需要去修改代码中的内容&#xff0c;其他人的MySQL和我的MySQL也不同&#xff0c;这时其他人只需要修改json文件中的内容&#xff0c;清晰明了&a…

基于STC8H系列单片机的定时器系统

基于STC8H系列单片机的定时器系统 STC8H4K64TL单片机介绍STC8H4K64TL单片机管脚图&#xff08;48个引脚&#xff09;STC8H4K64TL单片机串口仿真与串口通信STC8H4K64TL单片机管脚图&#xff08;32个引脚&#xff09;STC8H4K64TL单片机管脚图&#xff08;20个引脚&#xff09;STC…

Apollo使用(3):分布式docker部署

Apollo 1.7.0版本开始会默认上传Docker镜像到Docker Hub&#xff0c;可以按照如下步骤获取 一、获取镜像 1、Apollo Config Service 获取镜像 docker pull apolloconfig/apollo-configservice:${version} 我事先下载过该镜像&#xff0c;所以跳过该步骤。 2、Apollo Admin S…

计算机网络-配置路由器ACL(访问控制列表)

配置访问控制列表ACL 拓扑结构 拓扑结构如下&#xff1a; 要配置一个ACL&#xff0c;禁止PC0访问PC3&#xff0c;禁止PC4访问PC0&#xff0c;其它正常。 配置Router0 配置接口IP地址&#xff1a; interface fastethernet 0/0 ip address 192.168.1.1 255.255.255.0 no shu…

第三部分 图论 - 第2章 最小生成树

定义 首先我们先了解下生成树的定义&#xff1a; 无向图中&#xff0c;一个连通图的最小连通子图称作该图的生成树&#xff08;不能带环&#xff0c;保持连通&#xff0c;但边要尽可能的少&#xff09;。 有n个顶点的连通图的生成树有n个顶点和n-1条边。 那么最小生成树和生成…

决策树 和 集成学习、随机森林

决策树是非参数学习算法&#xff0c;可以解决分类问题&#xff0c;天然可以解决多分类问题&#xff08;不同于逻辑回归或者SVM&#xff0c;需要通过OVR&#xff0c;OVO的方法&#xff09;&#xff0c;也可以解决回归问题&#xff0c;甚至是多输出任务&#xff0c;并且决策树有非…

国内NAT服务器docker方式搭建rustdesk服务

前言 如果遇到10054,就不要设置id服务器!!! 由于遇到大带宽,但是又贵,所以就NAT的啦,但是只有ipv4共享和一个ipv6,带宽50MB(活动免费会升130MB~) https://bigchick.xyz/aff.php?aff322 月付-5 循环 &#xff1a;CM-CQ-Monthly-5 年付-60循环&#xff1a;CM-CQ-Annually-60官方…

数据结构第三讲:单链表的实现

数据结构第三讲&#xff1a;单链表的实现 1.什么是单链表2. 节点3.单链表的实现3.1节点的结构3.2打印单链表3.3申请一个新节点3.4单链表尾部插入3.5单链表头部插入3.6单链表的尾部删除3.7单链表头部删除3.8查找3.9在指定位置之前插入数据3.10在指定位置之后插入数据3.11删除pos…

VS+opencv+环境配置

下载opencv库。 版本 - OpenCV 下载完了是一个exe文件&#xff0c;&#xff08;可以更换目录&#xff09;直接双击&#xff0c;也就是压缩。 vs配置&#xff1a; 调试-调试属性 点编辑&#xff0c;加入这两个&#xff0c;路径根据自己的opencv库 3、链接器 测试&#xff1a;…

在Postman中引用JS库

前言 在做接口测试时&#xff0c;出于安全因素&#xff0c;请求参数需要做加密或者加上签名才能正常请求&#xff0c;例如&#xff1a;根据填写的请求参数进行hash计算进行签名。postman作为主流的接口调试工具也是支持请求预处理的&#xff0c;即在请求前使用JavaScript脚本对…

Redis:AOF持久化

1. 简介 以日志的形式来记录每个写操作&#xff0c;将redis执行的每个写操作记录下来&#xff08;读操作不记录&#xff09;&#xff0c;只需追加文件但不可以改写文件&#xff0c;redis启动之初会重新构建数据&#xff0c;即redis重启后会将日志中的所有写指令重新执行一遍以达…

扰动观测器DOB设计及其MATLAB/Simulink实现

扰动观测器(Disturbance Observer, DOB)是一种在控制系统中用于估计和补偿未知扰动的重要工具,以增强系统的鲁棒性和稳定性。其设计过程涉及系统建模、观测器结构设计以及控制律的调整。 扰动观测器设计原理 系统建模: 首先,需要建立被控对象的数学模型,明确系统的状态变…

2024第八届全国职工职业技能大赛“网络与信息安全管理员”赛项技术文件及任务书

2024第八届全国职工职业技能大赛“网络与信息安全管理员”赛项技术文件及任务书 一、赛项概述&#xff1a;二、竞赛形式&#xff1a;三、竞赛规则四、竞赛样题4.1、第一场4.1.2、实操闯关赛4.2、第二场4.3、第三场 需要培训可以私信博主 欢迎交流学习&#xff01; [X] &#x1…

【深入理解SpringCloud微服务】深入理解nacos

【深入理解SpringCloud微服务】深入理解nacos Nacos服务注册内存注册表内存注册表的更新通知客户端服务变更、服务同步、健康检查2.x版本nacos的变化 Nacos服务注册 spring-cloud-alibaba-nacos-discovery通过实现spring-cloud-commons规范定义的接口&#xff0c;完成nacos接入…