查看: 212| 回复: 0
跳转到指定楼层
上一主题 下一主题
收起左侧

[高频题] [面经] Meta Coding:没有地图的迷宫找奶酪(DFS + 回溯)

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
[面经] Meta Coding:没有地图的迷宫找奶酪(DFS + 回溯)
我的 Meta 面经第二题。这题有意思的地方在于没有地图、没有全局状态:迷宫只能靠一步步走出来。
题目
一只老鼠在迷宫里找奶酪。你只有两个函数可用:
    1. has_cheese()
    复制代码
    :老鼠当前在奶酪格时返回 True,否则 False。
    1. move(direction)
    复制代码
    :朝指定方向走一步。走成功返回 True,撞墙返回 False(位置不变)。
迷宫示例(
  1. #
复制代码
是墙,
  1. M
复制代码
是起点,
  1. C
复制代码
是奶酪):
  1. ######
  2. #M   #
  3. # ## #
  4. #  C #
  5. #    #
  6. ######
复制代码
实现
  1. find_cheese()
复制代码
,把老鼠带到奶酪处。
思路
相对坐标 + DFS + 回溯:
  • 用相对起点的坐标 (0, 0) 记录老鼠的位置。每次 move 成功,坐标加上对应方向的偏移,这样你始终知道自己相对出发点在哪。
    1. seen
    复制代码
    存走过的相对坐标,防止绕圈。
  • 每到一格先查
    1. has_cheese()
    复制代码
    。然后逐个方向尝试:去过的格子跳过,没去过的先
    1. move
    复制代码
    过去再递归;如果递归无功而返(死路),就朝来时的方向
    1. move
    复制代码
    回去,再试下一个方向。
  • 方向表按上/下/左/右排列,第
    1. i
    复制代码
    个方向的反方向正好是
    1. i ^ 1
    复制代码
    ,回溯时不用再查一张反方向表。
代码
  1. # Ordered so that index i ^ 1 is always the reverse move:
  2. # up <-> down, left <-> right.
  3. MOVES = [
  4.     ("up", 0, -1),
  5.     ("down", 0, 1),
  6.     ("left", -1, 0),
  7.     ("right", 1, 0),
  8. ]
  9. def find_cheese():
  10.     seen = set()
  11.     def walk(x, y):
  12.         if has_cheese():
  13.             return True
  14.         seen.add((x, y))
  15.         for i, (name, dx, dy) in enumerate(MOVES):
  16.             nx, ny = x + dx, y + dy
  17.             if (nx, ny) in seen:
  18.                 continue
  19.             if not move(name):
  20.                 continue  # wall: position unchanged, do not mark that cell
  21.             if walk(nx, ny):
  22.                 return True
  23.             move(MOVES[i ^ 1][0])  # step back the way we came
  24.         return False
  25.     return walk(0, 0)
复制代码
易错点
    1. move
    复制代码
    失败(撞墙)时位置不变:不要更新坐标,也不要把墙对面的格子标记为已访问,它可能从另一边绕得到。
  • 回溯必须真的
    1. move
    复制代码
    回去。如果记账的坐标和老鼠的实际位置脱节,后面全错。
    1. seen
    复制代码
    记的是相对坐标,不是路径:同一格从不同路线到达只算一次。
  • 递归深度最坏等于格子数。迷宫很大时改成显式栈,思路不变。
复杂度:每个格子最多进入一次,O(格子数)。
有问题欢迎讨论。

上一篇:[面经] Meta Coding:32 位整数按字节翻转(热身题)
下一篇:[面经] NVIDIA Coding:LRU 磁盘空间管理器(按容量淘汰)
您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表