↓快轉到主要內容
  1. LeetCode/

LeetCode 1210: Minimum Moves to Reach Target with Rotations

·2 分鐘· ·
LeetCode Hard Bfs Matrix
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: hard 第一次嘗試:2026-09-12

  • 提交紀錄:Accepted(heap)→ Accepted(deque)→ Accepted(狀態改成三維)

解題思路
#

蛇佔兩格,一開始在 (0,0)-(0,1),要走到 (n-1,n-2)-(n-1,n-1)。每一步可以往右、往下、或旋轉。

每一步成本都是 1,所以用 BFS。狀態用蛇尾(左上那格)的位置加上方向表示:(r, c, d),d = 0 是水平、d = 1 是垂直。

四種移動各自需要哪些格子是空的:

目前方向動作需要空的格子新狀態
水平往右(r, c+2)(r, c+1, 0)
水平往下(r+1, c)、(r+1, c+1)(r+1, c, 0)
水平順時針轉(r+1, c)、(r+1, c+1)(r, c, 1)
垂直往右(r, c+1)、(r+1, c+1)(r, c+1, 1)
垂直往下(r+2, c)(r+1, c, 1)
垂直逆時針轉(r, c+1)、(r+1, c+1)(r, c, 0)

水平時「往下」和「順時針轉」需要的格子一樣;垂直時「往右」和「逆時針轉」也一樣。

我的嘗試
#

第一版用 heap,存 (步數, 蛇尾, 蛇頭, 方向)。每一步成本都一樣,BFS 用普通 queue 就會依步數順序處理,heap 只是多了 log 的成本。第二版改成 deque。

第三版把狀態從「蛇尾加蛇頭的四個座標」簡化成「蛇尾加方向」,visited 改成三維陣列,也把六種移動整理成上面那張表的樣子。

正確解法
#

from collections import deque

class Solution:
    def minimumMoves(self, grid: List[List[int]]) -> int:
        n = len(grid)
        seen = {(0, 0, 0)}
        q = deque([(0, 0, 0, 0)])                     # r, c, d, moves
        while q:
            r, c, d, moves = q.popleft()
            if (r, c, d) == (n - 1, n - 2, 0):
                return moves
            nxt = []
            if d == 0:
                if c + 2 < n and grid[r][c + 2] == 0:
                    nxt.append((r, c + 1, 0))
                if r + 1 < n and grid[r + 1][c] == 0 and grid[r + 1][c + 1] == 0:
                    nxt.append((r + 1, c, 0))
                    nxt.append((r, c, 1))
            else:
                if r + 2 < n and grid[r + 2][c] == 0:
                    nxt.append((r + 1, c, 1))
                if c + 1 < n and grid[r][c + 1] == 0 and grid[r + 1][c + 1] == 0:
                    nxt.append((r, c + 1, 1))
                    nxt.append((r, c, 0))
            for state in nxt:
                if state not in seen:
                    seen.add(state)
                    q.append((*state, moves + 1))
        return -1

複雜度
#

時間 O(n^2):狀態最多 2n^2 個,每個最多 3 種移動。空間 O(n^2)。

要特別避免的錯誤
#

  • 旋轉時只檢查蛇頭要去的那格:旋轉時掃過的對角格也必須是空的。
  • 每步成本相同卻用 heap。
  • 狀態用四個座標:可以,但用蛇尾加方向比較簡潔,也不容易寫錯。

面試口說整理
#

每一步成本都是 1,所以用 BFS。我用蛇尾的位置加上水平或垂直表示狀態,水平時可以往右、往下、順時針轉,垂直時可以往下、往右、逆時針轉,每種動作各自檢查需要空的格子;旋轉需要的格子跟平移到另一邊相同。第一次到達終點狀態時的步數就是答案,狀態數是 O(n^2)。

相關文章

LeetCode 864: Shortest Path to Get All Keys
·2 分鐘
LeetCode Hard Bfs Bit-Manipulation Matrix
LeetCode 864 解題筆記:BFS 的狀態是 (位置, 拿到的鑰匙遮罩),同一格拿著不同鑰匙是不同的節點
LeetCode 4046: Minimum Cost Path With At Most K Turns
·2 分鐘
LeetCode Hard Graph Shortest-Path Heap Matrix
LeetCode 4046 解題筆記:Dijkstra 的狀態加上「上一步方向」和「已轉彎數」;同一格同方向時,先處理的成本較低,轉彎數也較少的話就支配後面的狀態
LeetCode 1377: Frog Position After T Seconds
·2 分鐘
LeetCode Hard Tree Dfs Bfs Graph Probability
LeetCode 1377 解題筆記:無向邊、seen 要記節點、提早到達目標時要看還能不能走
LeetCode 499: The Maze III
·2 分鐘
LeetCode Hard Graph Dijkstra Shortest-Path Heap Matrix
LeetCode 499 解題筆記:Dijkstra 的優先度用 (距離, 路徑字串),滾動途中經過洞就要停下
LeetCode 3905: Multi Source Flood Fill
·1 分鐘
LeetCode Medium Bfs Matrix
LeetCode 3905 解題筆記:多源 BFS 一次處理一層,先收集這一層每格的最大顏色,再一起寫回網格
LeetCode 987: Vertical Order Traversal of a Binary Tree
·1 分鐘
LeetCode Hard Tree Binary-Tree Bfs Sorting
LeetCode 987 解題筆記:收集 (欄, 列, 值) 三元組,排序後依欄分組