岛屿问题(dfs/bfs)
前言
简单记录一下这类题型的解题思路
一、岛屿数量
1. 思路
使用dfs遍历所有的岛屿,遍历过程中维护visited数组防止重复遍历。
class Solution {
// 随手记:为什么岛屿需要遍历四周?防止出现盲区,导致一块岛屿被误认为是两块
// 举例:{{'0', '1', '1', '1', '0', '1'},{'1', '1', '1', '1', '1', '1'}}
public int numIslands(char[][] grid) {
int row = grid.length;
int col = grid[0].length;
int[][] visited = new int[row][col];
int res = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (grid[i][j] == '1' && visited[i][j] == 0) {
dfs(grid, visited, i, j);
res++;
}
}
}
return res;
}
private void dfs(char[][] grid, int[][] visited, int row, int col) {
if (row < 0 || col < 0 || row >= grid.length || col >= grid[0].length) return;
if (grid[row][col] == '0' || visited[row][col] == 1) return;
visited[row][col] = 1;
dfs(grid, visited, row, col + 1);
dfs(grid, visited, row + 1, col);
dfs(grid, visited, row - 1, col);
dfs(grid, visited, row, col - 1);
}
}
2. 随手记
为什么岛屿需要遍历四周呢?这是为了防止出现盲区,导致一块岛屿被误认为是两块。
这道题很容易有个误区,认为从左上到右下遍历整个grid数组,所以在dfs时无需考虑左侧元素和上侧元素。我们通过下图举例描述,为什么这个思路有问题。
- 不考虑左侧元素:会导致上图中[0,1]位置在从[0,1]开始的这一轮dfs中被忽略。
- 不考虑上侧元素:会导致上图中[3,1]位置在从[0,1]开始的这一轮dfs中被忽略。
上述两种情况均会造成岛屿数量计算错误。