題目描述:給定一個 n×n 的二元矩陣 grid,其中 0 表示空格、1 表示障礙。從左上角 (0,0) 出發,目標是到達右下角 (n-1,n-1)。每一步可以朝 8 個方向移動(上下左右及四個對角),且只能經過值為 0 的格子。回傳最短路徑的長度(路徑長度 = 經過的格子數,包含起點和終點);若不存在路徑則回傳 -1。
解題思路:此題是最短路徑問題,每步移動的代價相同(皆為 1),因此使用 BFS(廣度優先搜尋) 可以保證找到最短路徑。
邊界條件處理(重要):若起點 (0,0) 或終點 (n-1,n-1) 的值為 1(障礙),直接回傳 -1。注意若 n=1 且 grid[0][0] == 0,起點即終點,路徑長度為 1。
BFS 步驟:
(0,0) 加入佇列,路徑長度初始化為 1,並將 grid[0][0] 標記為已訪問(設為 1 以避免重複訪問)。(n-1,n-1),回傳當前路徑長度。BFS 的關鍵性質:第一次到達終點時的步數就是最短路徑,因為 BFS 按層(距離)展開,距離相同的節點在同一層被處理。
時間複雜度:O(n²) — 矩陣共有 n² 個格子,每個格子最多被訪問一次。每次訪問檢查 8 個方向,為常數操作,總時間複雜度為 O(8·n²) = O(n²)。
空間複雜度:O(n²) — BFS 佇列最壞情況下(整個矩陣皆為 0)可能容納 O(n²) 個元素。若不允許修改原始 grid,需額外一個 visited 陣列,空間為 O(n²)。
1. If grid[0][0] == 1 or grid[n-1][n-1] == 1: return -1
2. If n == 1: return 1
3. Initialize BFS queue with (0, 0), mark grid[0][0] = 1, pathLen = 1
4. While queue not empty:
a. pathLen++
b. Process all nodes in current BFS level:
- For each (r, c) dequeued:
- For each of 8 directions (dr, dc):
- nr, nc = r+dr, c+dc
- Skip if out of bounds or grid[nr][nc] != 0
- If (nr, nc) == (n-1, n-1): return pathLen
- Mark grid[nr][nc] = 1, enqueue (nr, nc)
5. Return -1*A 搜尋 O(n² log n²)**:使用啟發函數(如切比雪夫距離 max(|r1-r2|, |c1-c2|))引導搜尋朝目標方向展開,能在許多情況下比純 BFS 更快收斂。但在最壞情況下時間複雜度與 BFS 相同,且實作較為複雜。適合在地圖較大且路徑明顯的場景下使用。
雙向 BFS O(n²):從起點和終點同時展開 BFS,當兩個搜尋邊界相交時找到最短路徑。理論上可將搜尋空間從 O(b^d) 降至 O(b^(d/2)),其中 b 為分支因子、d 為最短路徑長度。在本題中由於格子數固定為 n²,實際效益有限,但對於更大規模的圖搜尋問題效果顯著。