Snakes and Ladders
題目描述:給定一個 n×n 的棋盤,棋盤上有蛇和梯子。從格子 1 開始,每次可以擲骰子(1 到 6 點),移動到對應格子;若該格子有蛇或梯子,則必須移動到其目的地。求從格子 1 到格子 n² 所需的最少骰子次數;若無法到達則回傳 -1。
解題思路:本題是求「最少步數」的最短路徑問題,直觀上適合使用 BFS(廣度優先搜尋)。
最關鍵的挑戰在於座標轉換:棋盤採用蛇形(Boustrophedon)排列——第 1 行從左到右,第 2 行從右到左,依此交替。給定格子編號 num(1-indexed),需轉換為棋盤的 (row, col) 座標:
- 將
num - 1 轉為 0-indexed 的 pos
row_from_bottom = pos / n(從底部算起的行號)
col = pos % n;若該行是奇數行(從底部),則 col = n - 1 - col(反向)
- 實際矩陣行號
r = n - 1 - row_from_bottom
BFS 中,每個狀態是當前格子編號,每次嘗試擲骰 1 到 6,計算新格子編號,若有蛇/梯子則跳轉,若未訪問則加入佇列。BFS 保證第一次到達終點時的步數即為最少步數。
時間複雜度:O(n²) — 棋盤共有 n² 個格子,每個格子最多被 BFS 訪問一次;每次訪問最多嘗試 6 個骰子值,為常數。
空間複雜度:O(n²) — visited 陣列和 BFS 佇列的大小均為 O(n²)。
方法一:Dijkstra 最短路徑
將每個格子視為圖的節點,每次骰子移動為邊(邊權均為 1)。用 Dijkstra 求從格子 1 到格子 n² 的最短路徑。由於邊權相同,效果等同 BFS,但實作較複雜,時間複雜度 O(n² log n²),不如 BFS 直接。
方法二:動態規劃(僅適用於無環情況)
若棋盤不存在從較大格子跳回較小格子的梯子(即有向無環圖),可用 DP 正向計算每格的最少步數。但由於蛇可能造成循環,一般情況下 DP 不適用,BFS 天然處理循環(透過 visited 陣列避免重複訪問)。