岛屿数量
200. 岛屿数量
给你一个由 '1'
(陆地)和 '0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
输出:1
示例 2:
输入:grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
输出:3
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j]
的值为'0'
或'1'
DFS淹没相邻的1
每发现一个岛屿,岛屿数量加一,然后使用 DFS 将岛屿淹了,dfs就四件事:检查特殊情况,执行本次操作,进入下一层递归,返回。
class Solution {
// 主函数,计算岛屿数量
public int numIslands(char[][] grid) {
int res = 0;
int m = grid.length, n = grid[0].length;
// 遍历 grid
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
// 每发现一个岛屿,岛屿数量加一
res++;
// 然后使用 DFS 将岛屿淹了
dfs(grid, i, j);
}
}
}
return res;
}
// 从 (i, j) 开始,将与之相邻的陆地都变成海水。
// 特殊值,操作,进入子递归。
void dfs(char[][] grid, int i, int j) {
int m = grid.length, n = grid[0].length;
// 超出索引边界
if (i < 0 || j < 0 || i >= m || j >= n) {
return;
}
// 已经是海水了
if (grid[i][j] == '0') {
return;
}
// 将 (i, j) 变成海水
grid[i][j] = '0';
// 淹没上下左右的陆地
dfs(grid, i + 1, j);
dfs(grid, i, j + 1);
dfs(grid, i - 1, j);
dfs(grid, i, j - 1);
}
}
- 时间复杂度:O(MN),其中 M 和 N 分别为行数和列数。
- 空间复杂度:O(MN),在最坏情况下,整个网格均为陆地,深度优先搜索的深度达到 MN。
BFS淹没相邻的1
入队前淹没不会超时。无条件入队,出队后再淹没会超时。
class Solution {
public int numIslands(char[][] grid) {
int m = grid.length;
int n = grid[0].length;
int ans = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
bfs(grid, m, n, i, j);
ans++;
}
}
}
return ans;
}
public void bfs(char[][] grid, int m, int n, int i, int j) {
Queue<int[]> q = new LinkedList<>();
q.offer(new int[] { i, j });
// 对当前位置的操作:变为0
grid[i][j] = '0';
while (!q.isEmpty()) {
int[] a = q.poll();
int x = a[0];
int y = a[1];
int[][] dir = new int[][] { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
for (int k = 0; k < 4; k++) {
int newX = x + dir[k][0];
int newY = y + dir[k][1];
// 把与当前1相邻的1都加进去。队列里只存1。
// 对相邻位置的操作,变为0+入队。
if (newX >= 0 && newX < m && newY >= 0 && newY < n && grid[newX][newY] == '1') {
q.offer(new int[] { newX, newY });
grid[newX][newY] = '0';
}
}
}
return;
}
}
超时:
class Solution {
public int numIslands(char[][] grid) {
int m = grid.length;
int n = grid[0].length;
int ans = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
bfs(grid, m, n, i, j);
ans++;
}
}
}
return ans;
}
public void bfs(char[][] grid, int m, int n, int i, int j) {
Queue<int[]> q = new LinkedList<>();
q.offer(new int[] { i, j });
while (!q.isEmpty()) {
int[] a = q.poll();
int x = a[0];
int y = a[1];
grid[x][y] = '0';
int[][] dir = new int[][] { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
for (int k = 0; k < 4; k++) {
int newX = x + dir[k][0];
int newY = y + dir[k][1];
if (newX >= 0 && newX < m && newY >= 0 && newY <= n && grid[newX][newY] == '1') {
q.offer(new int[] { newX, newY });
}
}
}
return;
}
}