LeetCode 200. 岛屿数量(Python)

给你一个由 ‘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

示例 2:

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

提示:

m == grid.length n == grid[i].length 1 <= m, n <= 300 grid[i][j] 的值为
‘0’ 或 ‘1’

下面是一种使用深度优先搜索(DFS)的解决方案。思路是:对于每个格子,如果是陆地(‘1’),则启动一次 DFS,将与该陆地相连的所有陆地都“淹没”(即改为 ‘0’),这样就保证不重复计数。每启动一次 DFS,岛屿数量加 1。

def numIslands(grid):
    if not grid:
        return 0

    rows, cols = len(grid), len(grid[0])
    count = 0

    def dfs(i, j):
        # 检查边界和是否为水
        if i < 0 or i >= rows or j < 0 or j >= cols or grid[i][j] == '0':
            return
        # 将当前陆地标记为水,避免重复访问
        grid[i][j] = '0'
        # 递归遍历相邻的四个方向
        dfs(i + 1, j)
        dfs(i - 1, j)
        dfs(i, j + 1)
        dfs(i, j - 1)

    for i in range(rows):
        for j in range(cols):
            if grid[i][j] == '1':
                count += 1
                dfs(i, j)

    return count

带详细注释解释:

def numIslands(grid):
    # 如果输入的网格为空,则直接返回 0
    if not grid:
        return 0

    # 获取网格的行数和列数
    rows, cols = len(grid), len(grid[0])
    count = 0  # 用于记录岛屿数量

    # 定义一个深度优先搜索(DFS)的函数
    def dfs(i, j):
        # 边界检查:
        # 1. i 或 j 超出范围
        # 2. 当前格子为水('0'),则直接返回,不处理
        if i < 0 or i >= rows or j < 0 or j >= cols or grid[i][j] == '0':
            return
        # 将当前陆地格子标记为水('0'),避免后续重复访问
        grid[i][j] = '0'
        # 分别向上、下、左、右四个方向递归调用 DFS
        dfs(i + 1, j)
        dfs(i - 1, j)
        dfs(i, j + 1)
        dfs(i, j - 1)

    # 遍历整个网格
    for i in range(rows):
        for j in range(cols):
            # 如果遇到陆地('1')
            if grid[i][j] == '1':
                count += 1  # 计数加1,发现一个新的岛屿
                dfs(i, j)   # 调用 DFS 将该岛屿的所有部分都标记为水

    return count  # 返回岛屿的总数量

详细说明:
输入检查和初始化
首先判断 grid 是否为空,如果为空则返回 0。接着计算网格的行数 rows 和列数 cols,初始化岛屿计数器 count 为 0。
DFS 函数 dfs(i, j)
该函数接收当前格子的行坐标 i 和列坐标 j。
边界条件判断:
如果 i 或 j 越界(即小于 0 或大于等于行数/列数),或者当前格子的值为 ‘0’(表示水或已访问的陆地),则返回,不做处理。
标记访问:
将当前格子的值从 ‘1’ 改为 ‘0’,相当于将其“淹没”,防止在后续递归中重复计数。
递归遍历相邻格子:
分别向上下左右四个方向递归调用 DFS,确保能将与当前陆地相连的所有陆地都遍历到。
遍历整个网格
外层的双重循环遍历每一个格子。当遇到 ‘1’ 时,说明找到了一个新的岛屿,因此岛屿数量加 1,并调用 DFS 函数对该岛屿进行完整的遍历和标记。这样,在后续的遍历中,之前标记过的岛屿不会再次被计入。
返回结果
最终遍历完所有格子后,变量 count 就是岛屿的总数。


算法复杂度
• 时间复杂度
每个格子最多被访问一次,故时间复杂度为 O(mn),其中 m 为行数,n 为列数。
• 空间复杂度:
最坏情况下递归调用栈的深度可能达到 O(m
n)(当整个网格全为陆地时),但平均情况下一般较低。

你可能感兴趣的:(leetcode刷题,leetcode,深度优先,python)