OCI · Phone Coding

Oracle LC 200 岛屿数量:四连通 BFS 与边界验证

由 Oracle OCI 面经中的 LC 200 题号出发,给出明确训练假设、四方向遍历、复杂度和随机对照。

题目重点:由 Oracle OCI 面经中的 LC 200 题号出发,给出明确训练假设、四方向遍历、复杂度和随机对照。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练版输入为 0/1 的矩形二维网格,1 为陆地;只有上下左右连通,斜角不连通。
  • 不修改原网格;空网格或零列返回 0,非矩形输入报错。字符串 '0'/'1' 输入需先转换。

解题路线

  1. 从左到右扫描每一格,遇到未访问的陆地就把岛屿数加一。
  2. 用 BFS 访问该格所在四连通分量,邻居只有在合法边界、是陆地且未访问时才入队。
  3. 每格最多入队一次;visited 阻止环绕重复统计。题目若允许原地改写,也可把已访问陆地改为水以减少额外空间。

手动走一遍

网格 [[1,1,0],[0,1,0],[1,0,1]] 中前三个 1 连成一岛,底行两个 1 各独立,结果是 3。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

"""Count four-neighbor components of land without mutating the input grid."""

from collections import deque


def count_islands(grid: list[list[int]]) -> int:
    if not grid:
        return 0
    width = len(grid[0])
    if any(len(row) != width for row in grid):
        raise ValueError("grid must be rectangular")
    visited = set()
    count = 0
    for row in range(len(grid)):
        for column in range(width):
            if grid[row][column] != 1 or (row, column) in visited:
                continue
            count += 1
            visited.add((row, column))
            queue = deque([(row, column)])
            while queue:
                current_row, current_column = queue.popleft()
                for next_row, next_column in (
                    (current_row - 1, current_column),
                    (current_row + 1, current_column),
                    (current_row, current_column - 1),
                    (current_row, current_column + 1),
                ):
                    if (
                        0 <= next_row < len(grid)
                        and 0 <= next_column < width
                        and grid[next_row][next_column] == 1
                        and (next_row, next_column) not in visited
                    ):
                        visited.add((next_row, next_column))
                        queue.append((next_row, next_column))
    return count

复杂度

R×C 网格遍历 O(RC),visited 和队列最坏 O(RC);若允许原地修改可省 visited 集合,但队列仍可能达到 O(RC)。

易错点与追问

容易失分的边界

  • 把对角线也当连通。
  • 入队时不立即标记,重复入队膨胀队列。
  • 题目仅给题号就声称有特定障碍或动态修改追问。

继续深挖

  • 若有多次翻转一个格子的查询,静态 BFS 为什么不够?
  • 要求最大岛屿面积时如何复用同一遍历?
  • 网格远大于内存时如何处理分块边界上的连通关系?
✓已复制微信号!