Robotics SDE I Coop · Coding

Amazon Robotics:一滴水从给定点流下,哪些格子会湿?

按有向可达性遍历低处邻格,区分单起点扩散与两海洋逆向搜索。

题目重点:按有向可达性遍历低处邻格,区分单起点扩散与两海洋逆向搜索。

题意与假设

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

  • 训练合同四邻接、严格更低可通行,起点也湿;若相等高度可流,改≤且仍保留visited。
  • 仅求可达湿点,不模拟水量、速度、积水抬升或多个时间步。输入为非空矩形。

解题路线

  1. 将每个格子看节点,指向高度严格更低的邻格。从给定起点BFS/DFS,首次发现时放visited,最终集合就是所有有向可达节点。
  2. 正确性两方向:每个加入点由已湿点合法边到达,故有实际下降路径;对任意下降路径按长度归纳,前驱会出队检查后继,所有可达点都会被发现。
  3. 不要只选最低邻格;题目问所有可能变湿点,水可分支,所有低邻格都应遍历。strictly lower使图无环,但visited仍防不同路线重复处理同点。
  4. 作者拿LC417类比只是训练线索。两海洋题从边界反向沿高处找汇流集合;本题只有给定水源并沿低处前向探索,起点和方向都不同。

手动走一遍

训练地图[[5,4,6],[4,3,2]]从(0,0)出发,除(0,2)外都可湿;等高4邻接政策改变其他样例,不应暗中放宽。

Python 参考实现

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

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

from collections import deque


def wet_points(heights, start):
    """Four-neighbor movement, strictly downhill; includes starting cell."""
    if not heights or not heights[0] or any(len(row) != len(heights[0]) for row in heights):
        raise ValueError("expected nonempty rectangular grid")
    rows, cols = len(heights), len(heights[0])
    r,c = start
    if not (0 <= r < rows and 0 <= c < cols):
        raise ValueError("start out of bounds")
    wet = {start}
    queue = deque([start])
    while queue:
        r,c = queue.popleft()
        for nr,nc in ((r-1,c),(r+1,c),(r,c-1),(r,c+1)):
            if (0 <= nr < rows and 0 <= nc < cols and (nr,nc) not in wet
                    and heights[nr][nc] < heights[r][c]):
                wet.add((nr,nc))
                queue.append((nr,nc))
    return wet

复杂度

O(RC)时间与空间,每格检查最多4条边;只访问k个湿点时遍历O(k),矩形形状校验O(R)。

易错点与追问

容易失分的边界

  • 把本题直接换成双海洋交集。
  • 只沿一个最低点走。
  • 把可达当物理水量分布。

继续深挖

  • 允许平坡怎样改?
  • 若允许对角邻格?
  • 多水源和所有能到某汇点怎样做?
✓已复制微信号!