LeetCode - 200. 岛屿数量

287 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。


原题:200. 岛屿数量

题目大意:给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

例如:

输入:grid = [  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出:3

解题思路:

首先,我们需要在二维数组中对元素进行遍历,每当便利到一个元素的值是 1,那么就有一个岛屿。此时,与之上下左右相连的值为 1 的元素也属于这个岛屿,并且这个规则是递归的,也就是,「相连的 1」和「相连的 1 的相连的 1」都属于这个岛屿,因此,此处会用到递归。如果把值为 1 的元素的相连关系看作一个图的话,那么就是对这个图进行一次深度优先遍历。对图的深度优先便利的过程中需要标记访问过的元素,在这个题中,我们可以直接把访问过的元素的值修改为 0 ,而不需要在创建一个标记的数组。

当把一个值为 1 的元素的直接和间接相邻的 1 都标记为 0 之后,它所在的岛屿就在原始的数组中消失了,此时就可以接着遍历去寻找下一个岛屿,知道把整个二维数组都遍历完。

最终代码:

class Solution {
    public int numIslands(char[][] grid) {
        int r = grid.length;
        if (r == 0) {
            return 0;
        }
        int c = grid[0].length;
        int count = 0;
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                if (grid[i][j] == '1') {
                    count++;
                    dfs(grid, i, j);
                }
            }
        }
        return count;
    }
    private void dfs(char[][] grid, int i, int j) {
        grid[i][j] = '0';
        int[][] moves = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
        for (int[] move : moves) {
            int x = i + move[0], y = j + move[1];
            if (x >= 0 && x < grid.length && y >= 0 && y < grid[0].length && grid[x][y] == '1') {
                dfs(grid, x, y);
            }
        }
    }
}

代码中有几点值得注意的地方:

  • 统计岛屿数量的 count++ 在 dfs 方法的外面,不然会重复统计。
  • 在访问各个元素上下左右相邻元素的时候,一定要判断而为数组的边界,如果元素在数组的边界处,那么并不是每一个方向都有相邻的元素,忘记判断会导致程序异常。