前往
大廳
主題

LeetCode - 2258. Escape the Spreading Fire 解題心得

Not In My Back Yard | 2023-02-21 12:00:15 | 巴幣 0 | 人氣 191

題目連結:


題目意譯:
你被給定一個索引值從 0 開始且大小為 m × n 的二維整數陣列 grid,其代表著一片田地。每個格子有著以下三者之一的數值:
0 代表草地、
1 代表火、
2 代表一個你和火無法通過的牆壁。

你位於左上角的格子 (0, 0),而你想要移動到位於右下角格子 (m - 1, n - 1) 的安全屋。每一分鐘,你可以移動到相鄰的草地格子。在你移動後,每個著火的格子會擴散到所有不是牆壁的相鄰格子。

回傳在你可以安全地抵達安全屋的情況下,你在起身移動前最多還可以在停留在原地多少分鐘。如果這是不可能的,則回傳 -1。如果你不管停留多久都可以抵達安全屋,則回傳 10 ^ 9。

注意到即使你抵達安全屋後火勢馬上擴散到該位置,依舊可以視為安全地抵達安全屋。

一個格子與另一個格子相鄰,其代表著前者直接位於後者的北、東、南或是西側(即兩者的邊重疊了)。

限制:
m == grid.length
n == grid[i].length
2 ≦ m, n ≦ 300
4 ≦ m × n ≦ 2 × 10 ^ 4
grid[i][j] 只會是 0 、 1 或是 2 。
grid[0][0] == grid[m - 1][n - 1] == 0



範例測資:
範例 1:
輸入: grid = [[0,2,0,0,0,0,0],[0,0,0,2,2,1,0],[0,2,0,0,1,2,0],[0,0,2,2,2,0,2],[0,0,0,0,0,0,0]]
輸出: 3
解釋: 上圖顯示了你在原地停留 3 分鐘的情景。
你仍舊可以安全地抵達安全屋。
停留超過 3 分鐘的將會使你無法安全地抵達安全屋。

範例 2:
輸入: grid = [[0,0,0,0],[0,1,2,0],[0,2,0,0]]
輸出: -1
解釋: 上圖顯示了你馬上動身前往安全屋的情景。
火勢將擴散至你前往的任意格子,因此無法安全地抵達安全屋。
因此回傳 -1。

範例 3:
輸入: grid = [[0,0,0],[2,2,0],[1,2,0]]
輸出: 1000000000
解釋: 上圖顯示了一開始 grid 的樣子。
注意到火勢被牆壁包圍住,因此你永遠可以安全地抵達安全屋。
因此回傳 10 ^ 9。


解題思維:
首先把 grid 中的所有火源擴散出去(利用廣度優先搜尋(Breadth First Search,BFS)的精神),然後記錄火勢擴散到每一個格子所需要的分鐘數(一開始火在的位置為 0 秒)。

接著我們可以按照這題相同的精神去對「答案」進行二分搜尋法(Binary Search)。

假設現在我們猜了可以在原地待 M 分鐘。則此時跟一開始對火源進行 BFS 一樣,從 (0, 0) 開始為第 M 分鐘、移動到下一個格子則為 M + 1 分鐘等等。

期間如果移動到的格子(包含原本的位置 (0, 0))的分鐘數 ≧ 火勢蔓延過來的分鐘數則代表我們走到該格會出事,所以該格是走不了的。

唯一的例外是,當我們在 M' 分鐘時移動到安全屋 (m - 1, n - 1) 時,此時火勢擴散到安全屋的分鐘數只要不要 < M' 分鐘都是可行的(也就是說抵達分鐘數 > 火勢蔓延分鐘數才會出事,其他格子則是「≧」的大小關係)

而如果我們可以在原地等 M 分鐘並成功抵達安全屋的話,則代表我們有機會可以等得更久,所以可以猜更大的 M 值;反之,則代表在原地等太久了,需要猜小一點的 M 值。

最後可以收斂得到一個最大的分鐘數,代表我們可以在原地待的時間(如果連馬上出發都不能抵達安全屋則回傳 -1,此情況可以特殊處理等)。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作