返回

决胜“200. 岛屿数量”LeetCode难题:寻找岛屿的独门秘笈

前端

如何计算岛屿数量:深入理解 LeetCode 200

在计算机科学和算法的世界中,计算岛屿数量是一个常见的难题。想象一个网格地图,其中陆地用“1”表示,水域用“0”表示。你的任务是确定这个网格中岛屿的数量。一个岛屿是由相邻的陆地单元格组成的,这些单元格只能水平或垂直地连接。

在本文中,我们将深入探讨解决 LeetCode 上著名的“200. 岛屿数量”问题的步骤和技术。我们将从问题陈述开始,然后介绍解决步骤、代码实现、复杂度分析和常见问题解答。准备好在岛屿探索之旅中大展身手吧!

问题陈述

给定一个由“1”(陆地)和“0”(水)组成的二维网格,计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

解决步骤

要解决这个问题,我们需要遵循以下步骤:

  1. 定义岛屿: 岛屿是由水平方向和/或竖直方向上相邻的陆地单元格连接形成的区域。
  2. 遍历网格: 使用两个嵌套的循环遍历网格中的每个单元格。
  3. 检查当前单元格: 如果当前单元格是“1”,则表示该单元格是陆地,我们需要检查它是否属于某个岛屿。
  4. 搜索相邻单元格: 如果当前单元格是“1”,则需要检查其相邻单元格是否也是“1”。如果相邻单元格也是“1”,则它们属于同一个岛屿。
  5. 标记岛屿: 如果当前单元格是“1”并且其相邻单元格也是“1”,则我们可以将这些单元格标记为同一个岛屿。我们可以使用一个访问数组来记录哪些单元格已被访问过。
  6. 计数岛屿: 在遍历网格后,我们可以计算岛屿的数量。我们可以通过检查访问数组来确定网格中共有多少个岛屿。

代码实现

使用深度优先搜索(DFS)算法,我们可以实现上述步骤:

def num_islands(grid):
  """
  计算网格中岛屿的数量。

  参数:
    grid:由'1'(陆地)和'0'(水)组成的二维网格。

  返回:
    网格中岛屿的数量。
  """

  # 定义岛屿数量
  num_islands = 0

  # 创建一个访问数组来记录哪些单元格已被访问过
  visited = [[False for _ in range(len(grid[0]))] for _ in range(len(grid))]

  # 遍历网格
  for i in range(len(grid)):
    for j in range(len(grid[0])):

      # 如果当前单元格是陆地并且没有被访问过
      if grid[i][j] == '1' and not visited[i][j]:

        # 将当前单元格标记为已访问过
        visited[i][j] = True

        # 搜索相邻单元格
        dfs(grid, visited, i, j)

        # 计数岛屿
        num_islands += 1

  return num_islands


def dfs(grid, visited, i, j):
  """
  深度优先搜索算法。

  参数:
    grid:由'1'(陆地)和'0'(水)组成的二维网格。
    visited:访问数组,记录哪些单元格已被访问过。
    i:当前单元格的行索引。
    j:当前单元格的列索引。
  """

  # 检查当前单元格的相邻单元格
  for di, dj in [(1, 0), (-1, 0), (0, 1), (0, -1)]:

    # 计算相邻单元格的行索引和列索引
    next_i = i + di
    next_j = j + dj

    # 检查相邻单元格是否在网格内
    if next_i < 0 or next_i >= len(grid) or next_j < 0 or next_j >= len(grid[0]):
      continue

    # 检查相邻单元格是否为陆地并且没有被访问过
    if grid[next_i][next_j] == '1' and not visited[next_i][next_j]:

      # 将相邻单元格标记为已访问过
      visited[next_i][next_j] = True

      # 递归搜索相邻单元格
      dfs(grid, visited, next_i, next_j)

复杂度分析

  • 时间复杂度:O(mn),其中m和n分别为网格的行数和列数。
  • 空间复杂度:O(mn),因为我们需要创建一个访问数组来记录哪些单元格已被访问过。

常见问题解答

  1. 如何判断两个单元格是否相邻?
    两个单元格相邻,如果它们在水平方向或竖直方向上相邻。
  2. 如何标记岛屿?
    我们可以使用访问数组来标记岛屿。当我们访问一个单元格时,我们可以将该单元格标记为已访问过,并将其相邻的陆地单元格也标记为已访问过。
  3. 如何计数岛屿?
    在遍历网格后,我们可以检查访问数组来确定网格中共有多少个岛屿。我们可以通过计算访问数组中True单元格的数量来计数岛屿。
  4. 为什么使用深度优先搜索算法?
    DFS算法可以有效地探索相邻的单元格,并标记它们属于同一个岛屿。
  5. 如何优化算法?
    我们可以使用并查集算法来优化算法,它可以将不同的岛屿分组,并减少访问相同单元格的次数。

结论

解决 LeetCode“200. 岛屿数量”问题的过程是一个深入了解计算机科学和算法概念的绝佳机会。通过将问题分解为可管理的步骤,并使用DFS算法进行有效探索,我们可以高效地计算网格中岛屿的数量。希望本文为您提供了必要的知识和理解,以征服这个算法挑战!