200. Number of Islands

練習日期:2026-03-06

難度:Medium

類型:Array、Depth-First Search、Breadth-First Search、Union-Find、Matrix

📘 題目敘述

給你一個 m x n 的二維二進位網格 grid,它代表一張由 '1'(陸地)與 '0'(水)組成的地圖,請回傳島嶼的數量。

島嶼被水包圍,並且由水平或垂直相鄰的陸地連接形成。你可以假設網格的四個邊緣都被水包圍。

條件限制

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j]'0''1'

🧠 解題思路

這題我用 DFS 做「淹島」的概念。

我一格一格掃描 grid:只要遇到 '1',代表我發現了一座新的島,所以島的數量 count++。接著我就從這格開始做 DFS,把同一座島上所有連在一起的 '1' 全部改成 '0',等於把這座島整個消掉,避免之後掃描到同一座島又重複計數。

為了讓 DFS 可以往四個方向走,我用 dxdy 存上下左右的位移。

所有變數

  • mgrid 的列數
  • ngrid 的行數
  • dx:四個方向的 x 位移 {1, -1, 0, 0}
  • dy:四個方向的 y 位移 {0, 0, 1, -1}
  • count:目前已找到的島嶼數量
  • filled(x, y, grid):把 (x, y) 所在島嶼用 DFS 全部標記掉(把 '1''0'

🪜 主要流程步驟

1. 先記下 m、n,準備做整張圖的掃描

numIslands 一開始先設定:

  • m = grid.size()
  • n = grid[0].size()

2. 用雙層迴圈掃描每一格

對每個 (i, j)

  • 如果 grid[i][j] == '1',代表找到一座新島。我就先 count++,再呼叫 filled(i, j, grid) 把整座島清掉。

3. filled 的邊界判斷,避免走出地圖

filled(x, y, grid) 進來後,先檢查:

  • x < 0x >= my < 0y >= n,直接 return

這樣 DFS 才不會越界。


4. 如果這格是陸地,就把它改成水,並往四個方向擴散

如果 grid[x][y] == '1'

  • 先把它標記成走過:grid[x][y] = '0'
  • 然後用 k = 0..3 走四個方向,下一格是 (x + dx[k], y + dy[k]),對那格繼續呼叫 filled(...)

這一步會把「同一座島所有連通的陸地」全部清成 '0'


5. 掃描結束後,count 就是答案

因為每座島第一次被遇到時會 count++,而且同座島會立刻被 DFS 清掉,所以不會重複計數。

⏱️ 複雜度

  • 時間複雜度:O(m * n),每個格子最多被 DFS 處理一次(從 '1''0')。
  • 空間複雜度:O(m * n)(最壞情況遞迴深度可能到整張圖大小;若改成 iterative DFS/BFS 可避免遞迴爆棧的風險)。

💻 程式碼實作

class Solution {
public:
    int m;
    int n;
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
    int count = 0;

    void filled(int x, int y, vector<vector<char>>& grid) {
        if (x < 0 || x >= m || y < 0 || y >= n) {
            return;
        }
        if (grid[x][y] == '1') {
            grid[x][y] = '0';
            for (int k = 0; k < 4; k++) {
                filled(x + dx[k], y + dy[k], grid);
            }
        }
        return;
    }

    int numIslands(vector<vector<char>>& grid) {
        m = grid.size();
        n = grid[0].size();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == '1') {
                    count++;
                    filled(i, j, grid);
                }
            }
        }
        return count;
    }
};

https://leetcode.com/problems/number-of-islands/

作者:scottnick
撰寫日期:2026-03-06
類別:
原文連結:https://scottnick.github.io/cpp-notes/neetcode150/200-number-of-islands.html