图论系列(dfs岛屿) 9/26

server/2024/12/22 15:48:26/

一、统计封闭岛屿的数目
 

二维矩阵 grid 由 0 (土地)和 1 (水)组成。岛是由最大的4个方向连通的 0 组成的群,封闭岛是一个 完全 由1包围(左、上、右、下)的岛。

请返回 封闭岛屿 的数目。

输入:grid = [[1,1,1,1,1,1,1],[1,0,0,0,0,0,1],[1,0,1,1,1,0,1],[1,0,1,0,1,0,1],[1,0,1,1,1,0,1],[1,0,0,0,0,0,1],[1,1,1,1,1,1,1]]
输出:2
思路:

当grid[x][y]=0的时候,我们开始遍历;对每个节点进行dfs搜索

如果该节点正好是第一行第一列或者最后一行最后一列,那么直接返回false;(因为已经到达边界了,就无法被包围了)

如果该节点正好是1并且没有被访问过,返回true,周围是1,满足被包围的条件。

向四个方向递归调用dfs,只有同时满足true,才能说明是被包围的。

代码:
class Solution {boolean[][] visited;public int closedIsland(int[][] grid) {int res = 0;visited = new boolean[grid.length][grid[0].length];for (int i = 0; i < grid.length; i++) {for (int j = 0; j < grid[0].length; j++) {if (grid[i][j] == 0 && !visited[i][j]) {if(dfs(grid,i,j))res++;}}}return res;}public boolean dfs(int[][] grid, int x, int y) {if (x < 0 || x > grid.length - 1 || y < 0 || y > grid[0].length - 1)return false;if (grid[x][y] == 1||visited[x][y])return true;visited[x][y] = true;boolean up = dfs(grid, x - 1, y);boolean down = dfs(grid, x + 1, y);boolean left = dfs(grid, x, y - 1);boolean right = dfs(grid, x, y + 1);return up && down && left && right;}
}

二、被围绕的区域(和飞地的数量类似)

题意:

给定一个m*n的矩阵,由'X'、'O'组成。如果O的四周被X包围,那么O就要改成X;

思路:

1.出现在矩阵边缘的O定不会被包围,首先寻找未被包围的‘O’,通过dfs边缘的O,寻找连通子块。

        for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if ((i == 0 || i == board.length - 1 || j == 0 || j == board[0].length - 1) && board[i][j] == 'O') {dfs(board, i, j);}}}

2.然后剩下的O就是被包围的,将他们标记成X;最后将连通子块标记成O

        for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if (board[i][j] == 'O')board[i][j] = 'X';}}for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if (board[i][j] == 'A')board[i][j] = 'O';}}}
代码:
class Solution {boolean[][] visited;public void solve(char[][] board) {visited = new boolean[board.length][board[0].length];for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if ((i == 0 || i == board.length - 1 || j == 0 || j == board[0].length - 1) && board[i][j] == 'O') {dfs(board, i, j);}}}for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if (board[i][j] == 'O')board[i][j] = 'X';}}for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if (board[i][j] == 'A')board[i][j] = 'O';}}}public void dfs(char[][] board, int x, int y) {if (x < 0 || x > board.length - 1 || y < 0 || y > board[0].length - 1 || board[x][y] != 'O')return;board[x][y] = 'A';dfs(board, x - 1, y);dfs(board, x + 1, y);dfs(board, x, y - 1);dfs(board, x, y + 1);}
}

三、统计子岛屿

给定两个岛屿,看岛屿b中的岛屿是不是岛屿a中的子岛屿。

思路1(叠加法):

因为1是陆地,所以将两个岛屿中的1相加起来,如果为2,这就是他们重叠的陆地。

如果值为2的岛屿中含有值为1的陆地,那么他就不是子岛屿;

如果都是2,说明是子岛屿。

1.叠加两个岛屿的陆地

        for (int i = 0; i < grid2.length; i++) {for (int j = 0; j < grid2[0].length; j++) {if (grid2[i][j] == 1)grid2[i][j] += grid1[i][j];}}

2.然后在叠加后中寻找值都为2的岛屿

    public boolean dfs(int[][] grid, int x, int y) {if (x < 0 || x > grid.length - 1 || y < 0 || y > grid[0].length - 1||visited[x][y])return true;if (grid[x][y] !=2)return grid[x][y]==0;visited[x][y] = true;boolean up = dfs(grid, x - 1, y);boolean down = dfs(grid, x + 1, y);boolean left = dfs(grid, x, y - 1);boolean right = dfs(grid, x, y + 1);return up&&down&&left&&right;}

代码:
class Solution {boolean[][] visited;public int countSubIslands(int[][] grid1, int[][] grid2) {visited = new boolean[grid1.length][grid1[0].length];for (int i = 0; i < grid2.length; i++) {for (int j = 0; j < grid2[0].length; j++) {if (grid2[i][j] == 1)grid2[i][j] += grid1[i][j];}}int res = 0;for (int i = 0; i < grid2.length; i++) {for (int j = 0; j < grid2[0].length; j++) {if (grid2[i][j] == 2 && !visited[i][j]) {if(dfs(grid2,i,j))res++;}}}return res;}public boolean dfs(int[][] grid, int x, int y) {if (x < 0 || x > grid.length - 1 || y < 0 || y > grid[0].length - 1||visited[x][y])return true;if (grid[x][y] !=2)return grid[x][y]==0;visited[x][y] = true;boolean up = dfs(grid, x - 1, y);boolean down = dfs(grid, x + 1, y);boolean left = dfs(grid, x, y - 1);boolean right = dfs(grid, x, y + 1);return up&&down&&left&&right;}
}
思路2(淹没法):

在相同的位置处,如果矩阵2中是陆地,矩阵1中是海洋。那么这一定不是子岛屿,直接将该陆地的连通子块都淹没掉。

淹没完不是子岛屿的岛屿,剩下的就是子岛屿的岛屿。再次寻找即可

代码:
class Solution {boolean[][] visited;public int countSubIslands(int[][] grid1, int[][] grid2) {visited = new boolean[grid1.length][grid1[0].length];for (int i = 0; i < grid2.length; i++) {for (int j = 0; j < grid2[0].length; j++) {if(grid2[i][j]==1&&grid1[i][j]==0){dfs(grid2,i,j);}}}int res = 0;for (int i = 0; i < grid2.length; i++) {for (int j = 0; j < grid2[0].length; j++) {if (grid2[i][j] == 1 && !visited[i][j]) {dfs(grid2,i,j);res++;}}}return res;}public void dfs(int[][] grid, int x, int y) {if(x<0||y<0||x>grid.length-1||y>grid[0].length-1||visited[x][y]){return ;}if(grid[x][y]==0)return;visited[x][y]=true;grid[x][y]=0;dfs(grid,x-1,y);dfs(grid,x+1,y);dfs(grid,x,y+1);dfs(grid,x,y-1);}
}


http://www.ppmy.cn/server/126128.html

相关文章

【设计模式-中介者模式】

定义 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为设计模式&#xff0c;通过引入一个中介者对象&#xff0c;来降低多个对象之间的直接交互&#xff0c;从而减少它们之间的耦合度。中介者充当不同对象之间的协调者&#xff0c;使得对象之间的通信变得简单且…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-30

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-30 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-30目录1. Proof Automation with Large Language Models概览&#xff1a;论文研究背景&#xff1a;技术挑战&#xff1a;如何破局…

矩阵的特征值和特征向量

矩阵的特征值和特征向量是线性代数中非常重要的概念&#xff0c;用于描述矩阵对向量的作用&#xff0c;特别是在矩阵对向量的线性变换中的表现。它们帮助我们理解矩阵在某些方向上的缩放或旋转效果。 1. 特征值和特征向量的定义&#xff1a; 给定一个 n n n \times n nn 的…

每天五分钟玩转深度学习框架pytorch:多种定义损失函数的方法

本文重点 再编译神经网络的时有两个必要的元素,其中一个是损失函数,另外一个是优化器。前面的专栏我们已经介绍了优化器,本节课程我们介绍损失函数。损失函数属于神经网络训练的第5步。 nn.Module 和 nn.functional的损失函数 我们前面介绍过nn.Module和nn.functional的区…

ArcGIS与ArcGIS Pro去除在线地图服务名单

我们之前给大家分享了很多在线地图集&#xff0c;有些地图集会带有制作者信息&#xff0c;在布局制图的时候会带上信息影响出图美观。 一套GIS图源集搞定&#xff01;清新规划底图、影像图、境界、海洋、地形阴影图、导航图 比如ArcGIS&#xff1a; 比如ArcGIS Pro&#xff1a…

网络编程,tcp,守护进程化,前后台任务,bash与shell,会话

上篇&#xff0c;我们讲解了udp服务器与客户端的功能&#xff0c;这篇我们将使用tcp协议来进行编程&#xff1b;tcp服务器相比较与udp要更加稳定与安全&#xff0c;tcp服务器是面向连接的数据传输&#xff1b; 1. tcp服务器与客户端 下面是我实现的完整代码可以辅助下面的讲解…

Redis相关知识

参考Redis 消息队列的三种方案&#xff08;List、Streams、Pub/Sub&#xff09; - 知乎 (zhihu.com) 各种开源的 MQ 已经足够使用了&#xff0c;为什么需要用 Redis 实现 MQ 呢&#xff1f; 优点&#xff1a; 简单轻量&#xff1a;Redis是一个内存中的数据存储系统&#xff…

如何只用 CSS 制作网格?

来源&#xff1a;how-to-make-a-grid-like-graph-paper-grid-with-just-css 在看 用于打印到纸张的 CSS 这篇文章时&#xff0c;对其中的网格比较好奇&#xff0c;作者提供了 stackoverflow 的链接&#xff0c;就看到了来源的这个问题和众多回复。本文从里面挑选了一些个人比较…