力扣 200. 岛屿数量

题目说明

给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

  • 提示:
    • m == grid.length
    • n == grid[i].length
    • 1 <= m, n <= 300
    • grid[i][j] 的值为 '0''1'

示例

示例 1:

1
2
3
4
5
6
7
输入:grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
输出:1

示例 2:

1
2
3
4
5
6
7
输入:grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
输出:3

笔者理解

此题是一道数组算法问题,在力扣题库中被定义为中等题。

解法

当笔者阅读完此题后,因为数据量较小,直接采用了标记+DFS的方法,让我们来看看具体如何实现的吧。

实现

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
42
43
44
45
46
47
class Solution {
/**
* DFS
* 二维数组
*/

// x,y移动
int[] x = {-1, 1, 0, 0};
int[] y = {0, 0, -1, 1};

// 矩阵高宽
int m, n;
public int numIslands(char[][] grid) {
m = grid.length;
n = grid[0].length;

// 标记当前位置是否走过
boolean[][] isFind = new boolean[m][n];
int result = 0;

for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (!isFind[i][j] && grid[i][j] == '1') {
// 当前位置是陆地,并将周边陆地走遍
dfs(i, j, grid, isFind);
result++;
}
}
}

return result;
}

// 遍历将周围土地走遍
public void dfs(int i, int j, char[][] grid, boolean[][] isFind) {
// 越界或者走到水上
if (i < 0 || j < 0 || (m - i) * (n - j) <= 0 || isFind[i][j] || grid[i][j] == '0') {
return ;
}

isFind[i][j] = true;

for (int e = 0; e < 4; e++) {
dfs(i + x[e], j + y[e], grid, isFind);
}
}
}

时间和空间效率还行,可见此解法还比较适合此题。

image-20210918230245763

总结

本题是今天的一题,难度是为中等,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。