日期:2026年7月2日
LeetCode 題目連結:3286. Find a Safe Walk Through a Grid
解題想法
中等難度題。題目給定代表地圖的二維陣列 $grid$,假設尺寸為 $m \times n$,地圖中的數字代表走到這格會扣的血量,題目要求從左上角 $(0, 0)$ 出發走到右下角 $(m-1, n-1)$,如果能夠走到右下角回傳 True,如果無法走到右下角回傳 False。這類走格子的題目,我習慣用 BFS 解題。用 $que$ 儲存待走訪的格子座標,另外再開一個二維陣列 $visited$,用來儲存走到這格的最大血量,預設值為 $-1$,代表還沒有走到這格。持續從 $que$ 之中取出目前檢查的格子座標 $(r, c)$,如果 $r = m-1, c = n-1$ 回傳 True,如果還沒有走到終點則要做四方位檢查。時間複雜度為 $O(n^2)$。
Python 程式碼
Runtime: 63 ms, beats 83.49%. Memory: 19.47 MB, beats 97.17%.
class Solution:
def findSafeWalk(self, grid: List[List[int]], health: int) -> bool:
m, n = len(grid), len(grid[0]) # 地圖尺寸 m*n
visited = [[-1] * n for _ in range(m)] # 是否已走訪,-1 代表未走訪
visited[0][0] = health - grid[0][0] # 正值代表走到這格的 hp,起點可能會扣血
que = deque([(0, 0)]) # 待走訪佇列
# --- BFS ---
while que:
r, c = que.popleft() # 目前的位置
curr = visited[r][c] # 目前的血量
if r == m-1 and c == n-1: # 走到終點,回傳 True
return True
# 四方位檢查
for dr, dc in ((0, 1), (1, 0), (0, -1), (-1, 0)):
nr, nc = r + dr, c + dc
# 如果 (nr, nc) 未出界,目前的血量大於 (nr, nc) 會扣的血量,剩下的血量大於之前走到 (nr, nc) 的血量
if 0 <= nr < m and 0 <= nc < n and curr > grid[nr][nc] and curr - grid[nr][nc] > visited[nr][nc]:
visited[nr][nc] = curr - grid[nr][nc]
que.append((nr, nc))
return False