平安歸途 最安全的一條路 (圖論應用) Leetcode #2812

閱讀時間約 11 分鐘

題目敘述

題目給定一個二元矩陣,用1來代表小偷所在的位置,0代表沒有小偷。

每個格子點的安全分數為該點距離小偷的曼哈頓距離(Manhanttan distance)

一條路徑的安全分數是路徑上所有安全分數的最小值

移動的時候可以往上、下、左、右走一格。

請問從左上角走到右下角的最安全路徑的安全分數是多少


原本的英文題目敘述


測試範例

Example 1:

raw-image


Input: grid = [[1,0,0],[0,0,0],[0,0,1]]
Output: 0
Explanation: All paths from (0, 0) to (n - 1, n - 1) go through the thieves in cells (0, 0) and (n - 1, n - 1).


Example 2:

raw-image


Input: grid = [[0,0,1],[0,0,0],[0,0,0]]
Output: 2
Explanation: The path depicted in the picture above has a safeness factor of 2 since:
- The closest cell of the path to the thief at cell (0, 2) is cell (0, 0). The distance between them is | 0 - 0 | + | 0 - 2 | = 2.
It can be shown that there are no other paths with a higher safeness factor.


Example 3:

raw-image
Input: grid = [[0,0,0,1],[0,0,0,0],[0,0,0,0],[1,0,0,0]]
Output: 2
Explanation: The path depicted in the picture above has a safeness factor of 2 since:
- The closest cell of the path to the thief at cell (0, 3) is cell (1, 2). The distance between them is | 0 - 1 | + | 3 - 2 | = 2.
- The closest cell of the path to the thief at cell (3, 0) is cell (3, 2). The distance between them is | 3 - 3 | + | 0 - 2 | = 2.
It can be shown that there are no other paths with a higher safeness factor.
 

約束條件

Constraints:

  • 1 <= grid.length == n <= 400

輸入陣列的邊長n介於1~400之間。

  • grid[i].length == n

輸入陣列的邊長以n代表

  • grid[i][j] is either 0 or 1.

每個陣列元素一定是零(沒有小偷) 或 一(有小偷)。

  • There is at least one thief in the grid.

地圖中至少有一位小偷。


演算法 Dijkstra找最安全路徑


怎麼計算每個格子點的安全分數?

根據定義,
根據每個格子點和小偷的曼哈頓距離來計算。
( delta x + delta y = 水平距離差值 + 垂直距離差值)


怎麼找最安全路徑?

起點設為左上角,終點設為右下角。

使用Dijkstra algorithm,
每回合都從當前四聯通N4的鄰居取出安全分數最高的格子點,作為探索前進的方向


程式碼 Dijkstra找最安全路徑

class Solution:
def maximumSafenessFactor(self, grid: List[List[int]]) -> int:

# Heigh as well as width of board
h, w = len(grid), len(grid[0])

## Simple case:
# Either source or destination has thief.
# Not safe always => Safety score = 0
if grid[0][0] == 1 or grid[h-1][w-1] == 1:
return 0

## Dictionary
# key: coordination
# value: corresponding safeness score
safeness = defaultdict(lambda :-1)

bfs_queue = deque([])

## Step 1:
# Collect thief information
for r in range(h):
for c in range(w):
if grid[r][c] == 1:
safeness[r,c] = 0
bfs_queue.append((0, r, c))

## Step 2:
# Propagate safeness value based on Manhanttan distance to thief
N4_vector = [(-1,0),(1,0),(0,-1),(0,1)]
while bfs_queue:
dis, r, c = bfs_queue.popleft()

for dr, dc in N4_vector:
nr, nc = r + dr, c + dc

if 0 <= nr < h and 0 <= nc < w and safeness[nr,nc] == -1:
safeness[nr,nc] = dis + 1
bfs_queue.append((dis + 1, nr, nc))


## Step 3:
# Try to find safest path from source to destination, flip to negative to fit in python's minHeap in order to select safest path
safety_queue = [(-safeness[0,0], 0, 0)]

# Initialize to source point
seen = set([(0,0)])

# Dijkstra: always pick safer path first
while safety_queue:
safety, r, c = heappop(safety_queue)

# Flip back to positive value
safety *= -1

# Base case: we've reached destination
if (r, c) == (h-1, w-1):
return safety

## General cases:
# Check neighbor in N4, and update safety value, push back into priority queue on safety
for dr, dc in N4_vector:
nr, nc = r + dr, c + dc

# Neighbor is on the board, and it has not been seen yet.
if 0 <= nr < h and 0 <= nc < w and (nr, nc) not in seen:

# Update path safety = min{ safety value on the path so far}
path_safety = min(safety, safeness[nr,nc] )

# Push back into priorty queue
heappush(safety_queue, (-path_safety, nr, nc))

# Mark this neighbor as seen
seen.add((nr, nc))


# If no path to destination, return -1 as no solution
return -1

複雜度分析

時間複雜度: O(n^2 log n^2 )

需要一個2D掃描,掃描每個格子點恰好掃描一次,耗費O(n^2)時間。

接著使用Dijkstra algorithm + heap挑選最安全路徑,至多有O(n^2)個格子點,調整heap時,至多花費O(log n^2)的時間。


總共時間成本為O(n^2 + n^2 log n^2 ) = O( n^2 log n^2)


空間複雜度: O(n^2)

探索深度最深為O(n^2),最多就是將近探索整張圖,也就是queue的最大成本。


關鍵知識點

曼哈頓距離
= Manhantann distance
= 兩點之間的水平距離差距 + 垂直距離差距 = delta x + delta y


當遇到最短路徑最安全路徑最高分數路徑...等場景時,
聯想到圖論中的Dijkstra algorithm + priority queue

具體的優先權策略就根據題意進行計算即可
在本題中,最安全的路徑就是安全分數最高的路徑。


Reference

[1] Find the Safest Path in a Grid - LeetCode

80會員
417Content count
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
發表第一個留言支持創作者!
這篇文章討論了從二維整數陣列中挖掘金礦的問題。文章使用DFS模擬N4走法來解決問題,並提供了時間複雜度和空間複雜度的分析。這將有助於瞭解如何從地圖中挖取最多金礦。文章中提到了相關的關鍵知識點和參考資料。
題目敘述 輸入給定一個鏈結串列,整體看代表一個十進位的數字,各別看每個節點代表每個digit,分別從最高位~最低位個位數。 要求我們把原本的數字乘以二,並且以鏈結串列的形式返回答案。 原本的英文題目敘述
題目敘述 輸入給定一個鏈結串列的head node。 要求我們進行化簡,只要某個節點的右手邊存在比較大的節點,就刪除掉。 例如 5->2->13->3 5的右手邊有13,所以5刪除掉。 2的右手邊有13,所以2刪除掉。 13的右手邊沒有更大的節點,所以13留著。 3的右手邊沒有更大
這篇文章,會帶大家快速回顧DFS+回溯法框架(還沒看過或想複習的可以點連結進去)。 用DFS+回溯法框架,解開 組合數之和 Combination Sum 的全系列題目。 幫助讀者鞏固DFS+回溯法框架這個重要的知識點。 回顧 DFS+回溯法框架 白話的意思 # 列舉所以可能的情況,
今天的一魚三吃系列是透過 兩點之間是否存在一條路徑的題目,來回顧以前學過的DFS、BFS和Disjoint Set,鞏固圖論演算法的知識點。 英文的題目敘述在這裡 題目敘述 給定我們已知n個節點的圖,和圖上的每一條無向邊edges。 請問給定的起點start和終點end是否存在一條路徑可
今天的官方每日一題是Island Perimeter島嶼周長,很有趣的一題。 題目非常直觀好懂。也很適合拿來作為多角度複習、回顧圖論演算法的好題目。 英文的題目敘述在這裡 題目敘述 題目會給我們一個二維陣列當作地圖,格子點為1代表陸地,格子點為0代表海洋。 要求我們以四連通N4的方式拜訪
這篇文章討論了從二維整數陣列中挖掘金礦的問題。文章使用DFS模擬N4走法來解決問題,並提供了時間複雜度和空間複雜度的分析。這將有助於瞭解如何從地圖中挖取最多金礦。文章中提到了相關的關鍵知識點和參考資料。
題目敘述 輸入給定一個鏈結串列,整體看代表一個十進位的數字,各別看每個節點代表每個digit,分別從最高位~最低位個位數。 要求我們把原本的數字乘以二,並且以鏈結串列的形式返回答案。 原本的英文題目敘述
題目敘述 輸入給定一個鏈結串列的head node。 要求我們進行化簡,只要某個節點的右手邊存在比較大的節點,就刪除掉。 例如 5->2->13->3 5的右手邊有13,所以5刪除掉。 2的右手邊有13,所以2刪除掉。 13的右手邊沒有更大的節點,所以13留著。 3的右手邊沒有更大
這篇文章,會帶大家快速回顧DFS+回溯法框架(還沒看過或想複習的可以點連結進去)。 用DFS+回溯法框架,解開 組合數之和 Combination Sum 的全系列題目。 幫助讀者鞏固DFS+回溯法框架這個重要的知識點。 回顧 DFS+回溯法框架 白話的意思 # 列舉所以可能的情況,
今天的一魚三吃系列是透過 兩點之間是否存在一條路徑的題目,來回顧以前學過的DFS、BFS和Disjoint Set,鞏固圖論演算法的知識點。 英文的題目敘述在這裡 題目敘述 給定我們已知n個節點的圖,和圖上的每一條無向邊edges。 請問給定的起點start和終點end是否存在一條路徑可
今天的官方每日一題是Island Perimeter島嶼周長,很有趣的一題。 題目非常直觀好懂。也很適合拿來作為多角度複習、回顧圖論演算法的好題目。 英文的題目敘述在這裡 題目敘述 題目會給我們一個二維陣列當作地圖,格子點為1代表陸地,格子點為0代表海洋。 要求我們以四連通N4的方式拜訪
你可能也想看
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
不平凡的人類,仍然無法預知大自然天災何時會出現,希望在這不平靜的一天裡,大家都能平安度過。
Thumbnail
請全力呼吸,好好呼吸🙏🏻
蒼黑的盲夜,心底藏著浩然的星,仍無以計數地在發亮。我輕輕翻個身,就安逸地臥睡了,一溜煙就看到,老公坐在車上,正要載我去娘家,有位婆婆打開了我們的車門,向我們討了一隻玩偶,我好意告訴她說,「另外一隻毛茸茸的兔子,妳的孫女比較喜歡。」她本來有所顧忌,憂心孩子會過敏,但一聽聞孩子喜歡,就欣喜地拿了兩隻回去
Thumbnail
過年快到了,開開心心出遊,各位格友們記得遵守交通規則,看到大車要遠離一些!快快樂樂出門,要平平安安回家!多一分小心就多一份安全。寧可慢一點也不要搶快。 台灣1月29日至2月5日短短8天,發生9件與大型車輛有關死亡事故,但交通部長王國材日前在新春記者會談及道路安全時,他說了「生命價值跟民怨是兩難」,
Thumbnail
蒼蒼冷夜縮窄了範圍,卻讓深愛的彼此更親密相擁共渡,我慵困的找個容身之處,輕輕閉絕雙眼,便隱沒在這個世界,等躺熟穩了,就通往了幻境,在一條明亮的街道看見了大嫂面有難色的走來,她的父親也跟隨了過來,他們正要去參加堂妹的喪禮,我得知後,哀容地問,「她不是很年輕嗎?怎麼會這樣?」大嫂一臉惋惜地回,「事出都有
Thumbnail
位於新北與宜蘭之間的草嶺古道,每年秋天是許多旅人造訪的聖地,大家都想一睹滿山的雪白芒草。其實天氣好的時候,從上往下俯瞰龜山島,龜山島的紋路非常清晰,且這裡的位置觀賞龜山島看起來更近更大,還會看到媲美台東藍的湛藍海水,陽光打下來閃閃發亮,一點都不輸芒草的風采,正是這條路線可以一次收穫多種美景,
平安 目前這個世界每分每秒都激烈的變動著,傳播媒體的無遠弗屆與迅即,時空相異的人可能有感同身受的感覺。而更由此關心起身邊的人了。
Thumbnail
有一個大地主,擁有的土地是全村的五分之四,也就是說,村裡的土地有五分之四是他的,上千個村民擁有的土地加起來只有五分之一。
Thumbnail
你知道嗎,其實你從來就聽不見我的聲音,我也根本不會明白你耳中我的聲音是甚麼頻率。不過沒關係,留下的都是最好的。由衷的謝謝、謝謝,現在謝天再好不過了。
Thumbnail
第一個層次是混亂的層次,活在這個層次的人是很不安的,當我們在這裡時,頭腦會屬於一種亂糟糟的狀態,注意力不容易集中,心情也容易煩躁,這也就造成了生活上的失控與混亂。如果我們想要得到人生的平安,就必須逃脫這個混亂的層次,才能夠架構自己的人生,成為自己生命的主人。
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
不平凡的人類,仍然無法預知大自然天災何時會出現,希望在這不平靜的一天裡,大家都能平安度過。
Thumbnail
請全力呼吸,好好呼吸🙏🏻
蒼黑的盲夜,心底藏著浩然的星,仍無以計數地在發亮。我輕輕翻個身,就安逸地臥睡了,一溜煙就看到,老公坐在車上,正要載我去娘家,有位婆婆打開了我們的車門,向我們討了一隻玩偶,我好意告訴她說,「另外一隻毛茸茸的兔子,妳的孫女比較喜歡。」她本來有所顧忌,憂心孩子會過敏,但一聽聞孩子喜歡,就欣喜地拿了兩隻回去
Thumbnail
過年快到了,開開心心出遊,各位格友們記得遵守交通規則,看到大車要遠離一些!快快樂樂出門,要平平安安回家!多一分小心就多一份安全。寧可慢一點也不要搶快。 台灣1月29日至2月5日短短8天,發生9件與大型車輛有關死亡事故,但交通部長王國材日前在新春記者會談及道路安全時,他說了「生命價值跟民怨是兩難」,
Thumbnail
蒼蒼冷夜縮窄了範圍,卻讓深愛的彼此更親密相擁共渡,我慵困的找個容身之處,輕輕閉絕雙眼,便隱沒在這個世界,等躺熟穩了,就通往了幻境,在一條明亮的街道看見了大嫂面有難色的走來,她的父親也跟隨了過來,他們正要去參加堂妹的喪禮,我得知後,哀容地問,「她不是很年輕嗎?怎麼會這樣?」大嫂一臉惋惜地回,「事出都有
Thumbnail
位於新北與宜蘭之間的草嶺古道,每年秋天是許多旅人造訪的聖地,大家都想一睹滿山的雪白芒草。其實天氣好的時候,從上往下俯瞰龜山島,龜山島的紋路非常清晰,且這裡的位置觀賞龜山島看起來更近更大,還會看到媲美台東藍的湛藍海水,陽光打下來閃閃發亮,一點都不輸芒草的風采,正是這條路線可以一次收穫多種美景,
平安 目前這個世界每分每秒都激烈的變動著,傳播媒體的無遠弗屆與迅即,時空相異的人可能有感同身受的感覺。而更由此關心起身邊的人了。
Thumbnail
有一個大地主,擁有的土地是全村的五分之四,也就是說,村裡的土地有五分之四是他的,上千個村民擁有的土地加起來只有五分之一。
Thumbnail
你知道嗎,其實你從來就聽不見我的聲音,我也根本不會明白你耳中我的聲音是甚麼頻率。不過沒關係,留下的都是最好的。由衷的謝謝、謝謝,現在謝天再好不過了。
Thumbnail
第一個層次是混亂的層次,活在這個層次的人是很不安的,當我們在這裡時,頭腦會屬於一種亂糟糟的狀態,注意力不容易集中,心情也容易煩躁,這也就造成了生活上的失控與混亂。如果我們想要得到人生的平安,就必須逃脫這個混亂的層次,才能夠架構自己的人生,成為自己生命的主人。