← 返回编程题库
coding-min-knight-moves-bfs-grid困难免费版4000ms未尝试

马的最少步数 — 无限棋盘上的 BFS

Minimum Knight Moves — BFS on an Infinite Board

开始编码

给定无限棋盘上的一个目标格 (target_x, target_y)。一只马从原点 (0, 0) 出发,每一步从 (r, c) 可以跳到八个「日」字格 (r ± 1, c ± 2)(r ± 2, c ± 1)。求从 (0, 0)(target_x, target_y) 所需的最少马步数。棋盘没有墙、没有其他棋子、没有边界——它向四个方向无限延伸。

请实现 solution(target_x: int, target_y: int) -> int,返回一个非负整数,即在「以马步为边的无权图」上从 (0, 0)(target_x, target_y) 的 BFS 距离。坐标可以为负。

示例 1solution(0, 0) 返回 0——起点就是目标,不用走。示例 2solution(1, 1) 返回 2不是 0 也不是 4。马一步走不到 (1, 1)(8 种「日」字落点都不是 (1, 1)),需要先跨出去再绕回来:比如 (0, 0) → (2, -1) → (1, 1)。这是经典坑点——许多错误启发式会因为「不允许走到坐标为负的格子」而算成 4。示例 3solution(4, 5) 返回 3,比如 (0, 0) → (2, 1) → (4, 2) → (4, 5)

正解是在马步图上跑广度优先搜索。直接在 [-300, 300]² 上 BFS 太浪费;利用对称性(target_x, target_y) 的答案等于 (|target_x|, |target_y|) 的答案,因为马的走法在符号翻转下不变。把目标反射进第一象限,然后在 [-pad, |x| + pad] × [-pad, |y| + pad] 这个带小量 padding 的盒子里跑 BFS(pad = 2 就够)。padding 是必要的,正是因为像 (1, 1)(2, 2) 这种最优路径会短暂落到至少有一个坐标为负的格子上。这种「在边权一致的有限连接图上求最短跳数」的形态,正是分布式系统和量化基础设施里调度展开、依赖扩张、连通性归并的核心原语:任何能写成「在状态转移图上从 A 到 B 最少几步」的问题,只要你能写出转移函数,就能用 BFS 一击拿下。

约束条件

  • -300 ≤ target_x ≤ 300
  • -300 ≤ target_y ≤ 300
  • 起点固定为 (0, 0)
  • 马的走法是 8 个「日」字方向:(±1, ±2) 和 (±2, ±1)
  • 棋盘无穷大(没有边界可以撞;用对称性而不是夹逼)
  • 返回从 (0, 0) 到达 (target_x, target_y) 所需的最少马步数

样例

Case 1 · origin — already there

输入: [0,0]

期望: 0

起点就是目标,不需要任何移动,返回 0。这是最显然的边界情形。

Case 2 · (1,1) trap — needs a back-up move

输入: [1,1]

期望: 2

马走日,从 (0,0) 一步只能落在像 (1,2)、(2,1) 这些「对角格」上,永远到不了同色的 (1,1)。需要先跨出去再绕回来,最少 2 步:例如 (0,0) → (2,1) → (1,1)。这是经典坑点——很多贪心法会算成 3。

Case 3 · (4,5) — typical mid-distance LeetCode example

输入: [4,5]

期望: 3

LeetCode 1197 原题样例:(0,0) → (2,1) → (4,2) → (4,5) 共 3 步。这是 BFS 在中等距离下的标准结果。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · origin — already there

输入: [0,0]

期望: 0

起点就是目标,不需要任何移动,返回 0。这是最显然的边界情形。

Case 2 · (1,1) trap — needs a back-up move

输入: [1,1]

期望: 2

马走日,从 (0,0) 一步只能落在像 (1,2)、(2,1) 这些「对角格」上,永远到不了同色的 (1,1)。需要先跨出去再绕回来,最少 2 步:例如 (0,0) → (2,1) → (1,1)。这是经典坑点——很多贪心法会算成 3。

Case 3 · (4,5) — typical mid-distance LeetCode example

输入: [4,5]

期望: 3

LeetCode 1197 原题样例:(0,0) → (2,1) → (4,2) → (4,5) 共 3 步。这是 BFS 在中等距离下的标准结果。