WELCOME TO Pluto134340小行星

清风湿润,茶烟轻扬。

51.岛屿数量

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

方法dfs————来源:nettee

二叉树的 DFS 有两个要素:「访问相邻结点」和「判断 base case」。

第一个要素是访问相邻结点。二叉树的相邻结点非常简单,只有左子结点和右子结点两个。二叉树本身就是一个递归定义的结构:一棵二叉树,它的左子树和右子树也是一棵二叉树。那么我们的 DFS 遍历只需要递归调用左子树和右子树即可。

第二个要素是 判断 base case。一般来说,二叉树遍历的 base case 是 root == null。这样一个条件判断其实有两个含义:一方面,这表示 root 指向的子树为空,不需要再往下遍历了。另一方面,在 root == null 的时候及时返回,可以让后面的 root.left 和 root.right 操作不会出现空指针异常。

同理——图的相邻结点 : 上下左右;图的判断base case:超没超范围

如何避免重复遍历

答案是标记已经遍历过的格子。以岛屿问题为例,我们需要在所有值为 1 的陆地格子上做 DFS 遍历。每走过一个陆地格子,就把格子的值改为 2,这样当我们遇到 2 的时候,就知道这是遍历过的格子了。也就是说,每个格子可能取三个值:

0 —— 海洋格子
1 —— 陆地格子(未遍历过)
2 —— 陆地格子(已遍历过)

class Solution {
    // 岛屿数量计数器
    int count = 0;
    public int numIslands(char[][] grid) {
        // 处理空网格的边界情况,避免空指针
        if (grid == null || grid.length == 0) {
            return 0;
        }
        int rows = grid.length;
        int cols = grid[0].length;
        // 遍历网格中的每一个位置
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                // 发现未访问的陆地('1'),说明找到一个新岛屿
                if (grid[i][j] == '1') {
                    count++; // 岛屿数量加1
                    // 用DFS标记该岛屿的所有相邻陆地为已访问('2')
                    dfs(grid, i, j);
                }
            }
        }
        return count;
    }

    // 深度优先搜索:标记当前岛屿的所有相邻陆地为已访问
    public void dfs(char[][] grid, int r, int c) {
        // 检查当前坐标是否在网格范围内
        if (!inArea(grid, r, c))  return;
        // 如果当前位置不是未访问的陆地(是水或已访问的陆地),直接返回
        if (grid[r][c] != '1') {
            return;
        }
        // 标记为已访问(用'2'代替,避免重复计数)
        grid[r][c] = '2';
        // 向四个相邻方向递归遍历(上、下、左、右)
        dfs(grid, r - 1, c); //
        dfs(grid, r + 1, c); //
        dfs(grid, r, c - 1); //
        dfs(grid, r, c + 1); //
    }

    // 判断坐标(r,c)是否在网格的有效范围内
    public boolean inArea(char[][] grid, int r, int c) {
        return r >= 0 && r < grid.length 
                && c >= 0 && c < grid[0].length;
    }
}

【背!!n老师太牛了,讲的明明白白】

posted @ 2026-02-01 11:46  Pluto134340  阅读(2)  评论(0)    收藏  举报