SWE · VO Coding

Pinterest 八方向机器人:可到达格、障碍与双机器人边界

两篇 onsite 记录提到八方向机器人与障碍/双机器人追问;本文只实现明确的单机器人可达集合,并标明对角穿角约定。

题目重点:两篇 onsite 记录提到八方向机器人与障碍/双机器人追问;本文只实现明确的单机器人可达集合,并标明对角穿角约定。

题意与假设

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

  • 训练版矩形 grid 中 0 可走、1 障碍;输入起点 (row,column),输出所有可达坐标集合。
  • 对角移动只要求目标格可走,允许从两个正交障碍夹角穿过;题目未明确规则,若禁止穿角需额外检查侧邻格。
  • 双机器人追问可能要求可达集合并集、交集、是否相遇或最短同时行动路径,题目未明确,不指定一种为原题。

解题路线

  1. 检查输入矩形和起点是否合法;起点在障碍上则返回空集合。
  2. 用 BFS 队列存已发现格,每弹一格枚举八个方向,坐标合法、可走且未访问才入队;入队时立刻标记避免重复。
  3. 单障碍变体把该格标为不可走后重新遍历;若有大量动态障碍更新和查询,再讨论连通性索引,不能把一次 BFS 缓存结果直接复用。
  4. 双机器人先问目标:若只求各自可达区域,分别跑 BFS 再求并/交;若求同步相遇,状态是两个位置与时间,规模可远大于单机器人。

手动走一遍

3×3 网格中起点 (0,0),若 (1,0)、(0,1) 都是障碍,但 (1,1) 可走,本训练版允许对角进入 (1,1)。禁止穿角版本会在这一步停住,因此这组是澄清规则的关键测试。

Python 参考实现

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

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

"""Eight-neighbor reachable cells; diagonal corner cutting is allowed."""

from collections import deque


def reachable_cells(grid: list[list[int]], start: tuple[int, int]) -> set[tuple[int, int]]:
    if not grid or not grid[0]:
        return set()
    rows, columns = len(grid), len(grid[0])
    if any(len(row) != columns for row in grid):
        raise ValueError("grid must be rectangular")
    row, column = start
    if not (0 <= row < rows and 0 <= column < columns) or grid[row][column] != 0:
        return set()
    seen = {start}
    queue = deque([start])
    while queue:
        row, column = queue.popleft()
        for row_delta in (-1, 0, 1):
            for column_delta in (-1, 0, 1):
                if row_delta == column_delta == 0:
                    continue
                neighbor = (row + row_delta, column + column_delta)
                nr, nc = neighbor
                if 0 <= nr < rows and 0 <= nc < columns and grid[nr][nc] == 0 and neighbor not in seen:
                    seen.add(neighbor)
                    queue.append(neighbor)
    return seen

复杂度

R×C 网格每个可走格最多入队一次,时间 O(RC)、visited 与队列 O(RC);两个独立机器人可分别跑 O(RC),同步状态搜索可能达到 O((RC)²) 状态。

易错点与追问

容易失分的边界

  • 只写四方向模板,漏对角。
  • 未问穿角规则就在阻挡的两格之间斜穿。
  • 双机器人目标不明却编出同步相遇规则。
  • 入队后才标 visited,导致重复入队。

继续深挖

  • 若两个机器人必须在相同时间到同一格,状态和碰撞约束怎么定义?
  • 障碍变化后,缓存的可达集合何时失效?
  • 网格极大但障碍稀疏,怎样避免扫描全部格子?
✓已复制微信号!