题目:
给你一个由
'1'
(陆地)和'0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
解题思路:
该题是网格结构上DFS遍历的典型问题。
- 二叉树中深度优先遍历每个叶子结点,同样的网格中,就需要遍历自己的相邻结点,顺序的话无所谓,可以按照上下左右来遍历。
- 避免重复遍历。通过将已经走过的格子+1,来标记这是已经遍历的过的陆地格子。
- 遍历的算法已经初步构思完了,剩下的就是在dfs中添加逻辑。
时间复杂度与空间复杂度都为 O(m×n),因为最坏的情况下,递归调用栈空间会是M * N
代码:
class Solution {
public int numIslands(char[][] grid) {
int count = 0;
for (int x = 0; x < grid.length; x++) {
for (int y = 0; y < grid[0].length; y++) {
if(grid[x][y] == '1') {
dfs(grid, x, y);
count++;
}
}
}
return count;
}
public void dfs (char[][] grid, int x, int y) {
// 不是有效位置 || 海洋格子 || 已经遍历过的 -> 返回
if (!isValid(grid, x, y) || grid[x][y] == '0' || grid[x][y] == '2') {
return;
}
// 做一下标记
grid[x][y] = '2';
// 上下左右开始遍历
dfs(grid, x - 1, y);
dfs(grid, x + 1, y);
dfs(grid, x, y - 1);
dfs(grid, x, y + 1);
}
public boolean isValid(char[][] grid, int x, int y) {
return x < grid.length && x >= 0 && y >= 0 && y < grid[0].length;
}
}
总结:
dfs递归的时候,应该先想好怎么dfs的基础结构,怎么遍历,终止条件or越界条件,确保能递归网格或者树中的每个结点了,再进行逻辑层的设计。