200. 岛屿数量

import collections
from typing import List, Deque, Tuple

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        """
        计算二维网格中岛屿的数量。
        使用 BFS 辅助函数结构,并通过原地修改 grid 来标记已访问。

        Args:
            grid: 由 '1' (陆地) 和 '0' (水) 组成的二维列表。
                  注意:此方法会修改输入的 grid。

        Returns:
            岛屿的数量。
        """
        if not grid or not grid[0]:
            return 0

        rows = len(grid)
        cols = len(grid[0])
        island_count = 0
        # 方向数组,方便遍历邻居 (右, 左, 下, 上)
        directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]

        # 定义 BFS 辅助函数 (现在不需要 visited 参数)
        def bfs(r: int, c: int):
            """
            从 (r, c) 开始执行 BFS,将所有相连的陆地 '1' 修改为 '0'。
            """
            queue: Deque[Tuple[int, int]] = collections.deque()
            
            # 将起始点加入队列并立刻标记为已访问(改为 '0')
            # (注意:调用此函数前已确认 grid[r][c] == '1')
            queue.append((r, c))
            grid[r][c] = '0' 

            while queue:
                curr_r, curr_c = queue.popleft()

                # 探索四个方向的邻居
                for dr, dc in directions:
                    nr, nc = curr_r + dr, curr_c + dc

                    # 检查邻居是否有效且是陆地 ('1')
                    # 因为我们在入队时就修改,所以这里检查 '1' 就隐含了未访问
                    if (0 <= nr < rows and 
                        0 <= nc < cols and 
                        grid[nr][nc] == '1'):
                        
                        # 将邻居加入队列
                        queue.append((nr, nc))
                        # 标记邻居为已访问 (改为 '0')
                        grid[nr][nc] = '0'

        # --- 主函数逻辑 ---
        # 遍历网格中的每个单元格
        for r in range(rows):
            for c in range(cols):
                # 如果是陆地 ('1'),说明发现了一个新岛屿
                # 因为 BFS 会将访问过的 '1' 改为 '0',所以这里无需额外的 visited 检查
                if grid[r][c] == '1':
                    # 发现新岛屿
                    island_count += 1
                    # 调用 BFS “淹没”此岛屿的所有部分
                    bfs(r, c)
                            
        # 注意:此方法修改了原始 grid。如果需要保留原始 grid,
        # 应在开始时创建 grid 的副本进行操作。
        return island_count

# 示例用法
# solution = Solution()
# grid1 = [
#   ["1","1","1","1","0"],
#   ["1","1","0","1","0"],
#   ["1","1","0","0","0"],
#   ["0","0","0","0","0"]
# ]
# # 创建副本以防修改原 grid
# grid1_copy = [row[:] for row in grid1] 
# print(solution.numIslands(grid1_copy)) # 输出: 1

# grid2 = [
#   ["1","1","0","0","0"],
#   ["1","1","0","0","0"],
#   ["0","0","1","0","0"],
#   ["0","0","0","1","1"]
# ]
# grid2_copy = [row[:] for row in grid2]
# print(solution.numIslands(grid2_copy)) # 输出: 3
    def numIslands(self, grid: List[List[str]]) -> int:
        """
        计算二维网格中岛屿的数量。
        使用 DFS 递归辅助函数结构,并通过原地修改 grid 来标记已访问。

        Args:
            grid: 由 '1' (陆地) 和 '0' (水) 组成的二维列表。
                  注意:此方法会修改输入的 grid。

        Returns:
            岛屿的数量。
        """
        if not grid or not grid[0]:
            return 0

        rows = len(grid)
        cols = len(grid[0])
        island_count = 0

        # 定义 DFS 辅助函数
        def dfs(r: int, c: int):
            """
            从 (r, c) 开始执行 DFS,将所有相连的陆地 '1' 修改为 '0'。
            """
            # 1. 基准情况/停止条件:
            # a. 检查是否越界
            # b. 检查是否不是陆地 '1' (即 水 '0' 或 已访问过的标记 '0')
            if not (0 <= r < rows and 0 <= c < cols) or grid[r][c] != '1':
                return

            # 2. 标记当前单元格为已访问 (原地修改)
            grid[r][c] = '0' 

            # 3. 递归探索四个方向的邻居
            dfs(r + 1, c) # 向下
            dfs(r - 1, c) # 向上
            dfs(r, c + 1) # 向右
            dfs(r, c - 1) # 向左

        # --- 主函数逻辑 ---
        # 遍历网格中的每个单元格
        for r in range(rows):
            for c in range(cols):
                # 如果是陆地 ('1'),说明发现了一个新岛屿
                # 因为 DFS 会将访问过的 '1' 改为 '0',所以这里无需额外的 visited 检查
                if grid[r][c] == '1':
                    # 发现新岛屿
                    island_count += 1
                    # 调用 DFS “淹没”此岛屿的所有部分
                    dfs(r, c)
                            
        # 注意:此方法修改了原始 grid。如果需要保留原始 grid,
        # 应在开始时创建 grid 的副本进行操作。
        return island_count
        

### C语言实现计算岛屿数量算法 以下是基于引用内容以及相关知识构建的一个完整的C语言程序来解决岛屿数量问题。该方法通过深度优先搜索(DFS)遍历二维网格中的每一个位置,标记已访问过的陆地单元格。 #### 定义与初始化 在给定的 `grid` 中,每个 `'1'` 表示陆地,而 `'0'` 则表示水体。目标是找到相互连接的陆地组成的独立岛屿数量[^3]。 #### 主要逻辑 为了防止重复计数同一块岛屿上的多个陆地单元格,在发现一个新的未被访问的陆地时,调用辅助函数 `Search(x, y)` 来递归地标记这块岛屿的所有部分为已访问状态。这一步骤可以有效减少冗余操作并提高效率[^1]。 下面是具体的代码实现: ```c #include <stdio.h> #include <string.h> // 辅助函数用于修改当前节点及其相连的所有节点的状态 void Search(char **grid, int gridSize, int *gridColSize, int x, int y){ if (x < 0 || y < 0 || x >= gridSize || y >= (*gridColSize)) { return; } if(grid[x][y] != '1') { return; } // 将当前位置设置为‘0’代表已经访问过 grid[x][y] = '0'; // 对四个方向进行递归搜索 Search(grid, gridSize, gridColSize, x - 1, y); Search(grid, gridSize, gridColSize, x + 1, y); Search(grid, gridSize, gridColSize, x, y - 1); Search(grid, gridSize, gridColSize, x, y + 1); } int numIslands(char** grid, int gridSize, int* gridColSize){ if (!grid || gridSize == 0 || !(*gridColSize)){ return 0; } int count = 0; for(int i = 0; i < gridSize; ++i){ for(int j = 0; j < (*gridColSize); ++j){ if(grid[i][j] == '1'){ // 发现新岛屿 count++; // 调用dfs清除整个岛屿 Search(grid, gridSize, gridColSize, i, j); } } } return count; } ``` 上述代码实现了基本的功能需求,并遵循了标准输入输出模式下的最佳实践[^4]。 #### 测试案例 可以通过简单的测试数据验证此功能是否正常工作。例如创建一个小型矩阵模拟地图环境来进行调试和确认最终结果准确性。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值