LongDz 的数字文墨提案

200. 岛屿数量

3 min

题目

岛屿数量 中等

解法:DFS

思路

核心思想是使用深度优先搜索(DFS)洪水填充算法,遍历网格并标记访问过的陆地。

该方法正确是因为每个岛屿是一个四连通分量。当从某块未访问的陆地出发进行DFS时,会递归访问并标记该岛屿所有相连的陆地,确保整个连通分量仅被计数一次。由于外层循环遍历所有单元格,且已访问的陆地会被标记为’0’,因此每个岛屿恰好被计数一次,不会遗漏或重复。

  • Step 1: 遍历网格中的每个单元格
  • Step 2: 当发现值为’1’的单元格时,岛屿计数加1
  • Step 3: 从该单元格开始DFS,将所有相连的’1’标记为’0’
  • Step 4: DFS递归访问上下左右四个方向,边界检查防止越界

复杂度

  • 时间复杂度: O(m×n)O(m \times n),其中m和n分别是网格的行数和列数。每个单元格最多被访问一次。
  • 空间复杂度: O(m×n)O(m \times n),最坏情况下递归调用栈的深度达到网格大小(整个网格都是陆地)。

代码

class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        int ans = 0;

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == '1') {
                    ans++;
                    dfs(grid, i, j);
                }
            }
        }

        return ans;
    }

    void dfs(vector<vector<char>>& grid, int i, int j) {
        int m = grid.size();
        int n = grid[0].size();

        if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == '0') {
            return;
class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        int ans = 0;

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == '1') {
                    ans++;
                    dfs(grid, i, j);
                }
            }
        }

        return ans;
    }

    void dfs(vector<vector<char>>& grid, int i, int j) {
        int m = grid.size();
        int n = grid[0].size();

        if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == '0') {
            return;
        }

        grid[i][j] = '0';  // 标记为已访问

        dfs(grid, i + 1, j);
        dfs(grid, i - 1, j);
        dfs(grid, i, j + 1);
        dfs(grid, i, j - 1);
    }
};