平安歸途 最安全的一條路 (圖論應用) 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

86會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言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的方式拜訪
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
不平凡的人類,仍然無法預知大自然天災何時會出現,希望在這不平靜的一天裡,大家都能平安度過。
Thumbnail
請全力呼吸,好好呼吸🙏🏻
蒼黑的盲夜,心底藏著浩然的星,仍無以計數地在發亮。我輕輕翻個身,就安逸地臥睡了,一溜煙就看到,老公坐在車上,正要載我去娘家,有位婆婆打開了我們的車門,向我們討了一隻玩偶,我好意告訴她說,「另外一隻毛茸茸的兔子,妳的孫女比較喜歡。」她本來有所顧忌,憂心孩子會過敏,但一聽聞孩子喜歡,就欣喜地拿了兩隻回去
Thumbnail
過年快到了,開開心心出遊,各位格友們記得遵守交通規則,看到大車要遠離一些!快快樂樂出門,要平平安安回家!多一分小心就多一份安全。寧可慢一點也不要搶快。 台灣1月29日至2月5日短短8天,發生9件與大型車輛有關死亡事故,但交通部長王國材日前在新春記者會談及道路安全時,他說了「生命價值跟民怨是兩難」,
Thumbnail
蒼蒼冷夜縮窄了範圍,卻讓深愛的彼此更親密相擁共渡,我慵困的找個容身之處,輕輕閉絕雙眼,便隱沒在這個世界,等躺熟穩了,就通往了幻境,在一條明亮的街道看見了大嫂面有難色的走來,她的父親也跟隨了過來,他們正要去參加堂妹的喪禮,我得知後,哀容地問,「她不是很年輕嗎?怎麼會這樣?」大嫂一臉惋惜地回,「事出都有
Thumbnail
位於新北與宜蘭之間的草嶺古道,每年秋天是許多旅人造訪的聖地,大家都想一睹滿山的雪白芒草。其實天氣好的時候,從上往下俯瞰龜山島,龜山島的紋路非常清晰,且這裡的位置觀賞龜山島看起來更近更大,還會看到媲美台東藍的湛藍海水,陽光打下來閃閃發亮,一點都不輸芒草的風采,正是這條路線可以一次收穫多種美景,
平安 目前這個世界每分每秒都激烈的變動著,傳播媒體的無遠弗屆與迅即,時空相異的人可能有感同身受的感覺。而更由此關心起身邊的人了。
Thumbnail
有一個大地主,擁有的土地是全村的五分之四,也就是說,村裡的土地有五分之四是他的,上千個村民擁有的土地加起來只有五分之一。
Thumbnail
你知道嗎,其實你從來就聽不見我的聲音,我也根本不會明白你耳中我的聲音是甚麼頻率。不過沒關係,留下的都是最好的。由衷的謝謝、謝謝,現在謝天再好不過了。
Thumbnail
第一個層次是混亂的層次,活在這個層次的人是很不安的,當我們在這裡時,頭腦會屬於一種亂糟糟的狀態,注意力不容易集中,心情也容易煩躁,這也就造成了生活上的失控與混亂。如果我們想要得到人生的平安,就必須逃脫這個混亂的層次,才能夠架構自己的人生,成為自己生命的主人。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
不平凡的人類,仍然無法預知大自然天災何時會出現,希望在這不平靜的一天裡,大家都能平安度過。
Thumbnail
請全力呼吸,好好呼吸🙏🏻
蒼黑的盲夜,心底藏著浩然的星,仍無以計數地在發亮。我輕輕翻個身,就安逸地臥睡了,一溜煙就看到,老公坐在車上,正要載我去娘家,有位婆婆打開了我們的車門,向我們討了一隻玩偶,我好意告訴她說,「另外一隻毛茸茸的兔子,妳的孫女比較喜歡。」她本來有所顧忌,憂心孩子會過敏,但一聽聞孩子喜歡,就欣喜地拿了兩隻回去
Thumbnail
過年快到了,開開心心出遊,各位格友們記得遵守交通規則,看到大車要遠離一些!快快樂樂出門,要平平安安回家!多一分小心就多一份安全。寧可慢一點也不要搶快。 台灣1月29日至2月5日短短8天,發生9件與大型車輛有關死亡事故,但交通部長王國材日前在新春記者會談及道路安全時,他說了「生命價值跟民怨是兩難」,
Thumbnail
蒼蒼冷夜縮窄了範圍,卻讓深愛的彼此更親密相擁共渡,我慵困的找個容身之處,輕輕閉絕雙眼,便隱沒在這個世界,等躺熟穩了,就通往了幻境,在一條明亮的街道看見了大嫂面有難色的走來,她的父親也跟隨了過來,他們正要去參加堂妹的喪禮,我得知後,哀容地問,「她不是很年輕嗎?怎麼會這樣?」大嫂一臉惋惜地回,「事出都有
Thumbnail
位於新北與宜蘭之間的草嶺古道,每年秋天是許多旅人造訪的聖地,大家都想一睹滿山的雪白芒草。其實天氣好的時候,從上往下俯瞰龜山島,龜山島的紋路非常清晰,且這裡的位置觀賞龜山島看起來更近更大,還會看到媲美台東藍的湛藍海水,陽光打下來閃閃發亮,一點都不輸芒草的風采,正是這條路線可以一次收穫多種美景,
平安 目前這個世界每分每秒都激烈的變動著,傳播媒體的無遠弗屆與迅即,時空相異的人可能有感同身受的感覺。而更由此關心起身邊的人了。
Thumbnail
有一個大地主,擁有的土地是全村的五分之四,也就是說,村裡的土地有五分之四是他的,上千個村民擁有的土地加起來只有五分之一。
Thumbnail
你知道嗎,其實你從來就聽不見我的聲音,我也根本不會明白你耳中我的聲音是甚麼頻率。不過沒關係,留下的都是最好的。由衷的謝謝、謝謝,現在謝天再好不過了。
Thumbnail
第一個層次是混亂的層次,活在這個層次的人是很不安的,當我們在這裡時,頭腦會屬於一種亂糟糟的狀態,注意力不容易集中,心情也容易煩躁,這也就造成了生活上的失控與混亂。如果我們想要得到人生的平安,就必須逃脫這個混亂的層次,才能夠架構自己的人生,成為自己生命的主人。