飞地的数量

1020. 飞地的数量 - 力扣(LeetCode)

给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。

一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。

返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。

示例 1:

img

1
2
3
输入:grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
输出:3
解释:有三个 1 被 0 包围。一个 1 没有被包围,因为它在边界上。

示例 2:

img

1
2
3
输入:grid = [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
输出:0
解释:所有 1 都在边界上或可以到达边界。

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 500
  • grid[i][j] 的值为 01

本题要求找到不靠边的陆地面积,那么我们只要从周边找到陆地然后 通过 dfs或者bfs 将周边靠陆地且相邻的陆地都变成海洋,然后再去重新遍历地图的时候,统计此时还剩下的陆地就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Solution {
int count = 0;
public int numEnclaves(int[][] grid) {

//将上下边界的岛屿填平
for(int i = 0; i < grid[0].length; i++){
if(grid[0][i] == 1) dfs(grid, 0, i);
if(grid[grid.length-1][i] == 1) dfs(grid, grid.length-1, i);
}
//将左右边界的岛屿填平
for(int i = 0; i < grid.length; i++){
if(grid[i][0] == 1) dfs(grid, i, 0);
if(grid[i][grid[0].length-1] == 1) dfs(grid, i, grid[0].length-1);
}
//填平了处于边界的岛屿再统计岛屿单元格的数量
count = 0;
for(int i = 0; i < grid.length; i++){
for(int j = 0; j < grid[0].length; j++){
if(grid[i][j] == 1){
dfs(grid, i, j);
}
}
}
return count;
}
public void dfs(int[][] grid, int x, int y){
//越界或者该节点已被访问,或遇到到了非岛屿,直接return
if(x < 0 || y < 0 || x >= grid.length || y >= grid[0].length || grid[x][y] == 0){
return;
}

//访问该节点
grid[x][y] = 0; //访问的岛屿直接填平
count ++;
dfs(grid, x - 1, y); //向上
dfs(grid, x , y - 1); //向左
dfs(grid, x + 1, y); //向下
dfs(grid, x , y + 1); //向右

}
}

飞地的数量
http://example.com/2023/09/17/算法/图/4. 飞地的数量/
作者
PALE13
发布于
2023年9月17日
许可协议