進階圖論應用: 解開數字鎖 Open the Lock_Leetcode #752

更新 發佈閱讀 9 分鐘

題目敘述

題目會給我們一個4位數字的數字鎖,還有解鎖的密碼target,和陷阱數字deadends(假如遇到的話鎖會直接卡住,不能在撥動轉盤了)。

預設開始的狀態是0000,請問,最少要撥動轉盤幾次才能解鎖?


題目的原文敘述


測試範例

Example 1:

Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202"
Output: 6
Explanation:
A sequence of valid moves would be "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202".
Note that a sequence like "0000" -> "0001" -> "0002" -> "0102" -> "0202" would be invalid,
because the wheels of the lock become stuck after the display becomes the dead end "0102".

Example 2:

Input: deadends = ["8888"], target = "0009"
Output: 1
Explanation: We can turn the last wheel in reverse to move from "0000" -> "0009".

Example 3:

Input: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888"
Output: -1
Explanation: We cannot reach the target without getting stuck.

約束條件

Constraints:

  • 1 <= deadends.length <= 500

陷阱數字的數量介於 1個~500個。

  • deadends[i].length == 4

陷阱數字也是4-digits的數字。

  • target.length == 4

解鎖密碼也是4-digits的數字。

  • target will not be in the list deadends.

題目保證 解鎖密碼不會是陷阱數字。

  • target and deadends[i] consist of digits only.

解鎖密碼和陷阱數字都是0~9的數字所構成。


演算法 映射到圖論中的最短路徑Shortest Path


可以把數字鎖的每個數字映射到圖論中的節點(代表一個狀態)

可以透過轉動一格抵達的數字彼此有一條邊連著,權重為1,代表移動成本為一步,撥動轉盤一次

那麼,原本題目所求: 從0000到解鎖密碼target的最小轉盤撥動次數 就等於 從0000到解鎖密碼target的最短路徑長度

這是一張等權重BFS在等權重的圖先天具有尋找最短路徑的特質


所以用BFS搭配N2 往上或往下撥動一格的位移向量,從出發點開始探索整張圖,當成功解鎖時,當下的步數 = 從0000到解鎖密碼target的最小轉盤撥動次數 = 從0000到解鎖密碼target的最短路徑長度

程式碼 用BFS去找等權重圖中的最短路徑Shortest Path

class Solution:
def openLock(self, deadends: List[str], target: str) -> int:

# Starting number 0000 = 0
start = 0000

# Set of deadend number
deadends = set( map(int, deadends) )

# Target number
target = int(target)

# visited set to avoid repeated traversal
seen = set([start])

# Each digit can either go up or go down
# 0 <-> 1 <-> 2 ... <-> 9 <-> 0
rotation = (+1, -1)
bfs_queue = deque( [ (start, 0) ] ) if start not in deadends else []

# Try to open the lock with BFS to find the minimal count of rotations
while bfs_queue:

cur, step = bfs_queue.popleft()

# Yeah! we meet the target number
if cur == target:
return step

# Each round, we can pick one digit and rotate it
for i in range(4):

cur_digit = (cur // (10**i)) % 10

# Each digit can either go up or go down
for r in rotation:
offset = (( cur_digit + r + 10) % 10 - cur_digit) * (10 ** i)
next_state = cur + offset

# Skip when meeting deadend numbers
if next_state in deadends: continue

# Skip when this number is seen before
if next_state in seen: continue

bfs_queue.append( (next_state, step+1) )
seen.add( next_state )

# ----------------------------------------------------
# -1 stands for No solution
return -1

複雜度分析 用BFS去找等權重圖中的最短路徑Shortest Path

時間複雜度:

從出發點開始探索整張圖,每個數字0000~9999最多拜訪一次,所需時間為O(10^4) = O(1) 常數級別。

空間複雜度:

空間成本耗費在BFS Queue上,Worst case是幾乎拜訪所有數字 = O(10^4) = O(1) 常數級別。

另外,建造deadends和seen也需要相對集合所需的空間,但是,密碼鎖的數字範圍0000~9999是固定的,所以,也可以是為常數空間O(1)。


關鍵知識點

可以把數字鎖的每個數字映射到圖論中的節點(代表一個狀態)

可以透過轉動一格抵達的數字彼此有一條邊連著,權重為1,代表移動成本為一步,撥動轉盤一次

那麼,原本題目所求: 從0000到解鎖密碼target的最小轉盤撥動次數 就等於 從0000到解鎖密碼target的最短路徑長度

這是一張等權重BFS在等權重的圖先天具有尋找最短路徑的特質


可以一起複習 最接近的迷宮出口 Nearest Exit from Entrance in Maze_Leetcode 1926這題,用到的都是同一個性質: 用BFS去找等權重的圖的最短路徑長度。


Reference:

[1] Open the Lock - LeetCode

留言
avatar-img
小松鼠的演算法樂園
99會員
428內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
2024/09/26
Leetcode 729. My Calendar I 給定一個行事曆的class定義和行程安排的介面interface。 請完成下列function 1.建構子MyCalendar() 初始化MyCalendar物件 2.boolean book(int start, int end) 插入新行程
Thumbnail
2024/09/26
Leetcode 729. My Calendar I 給定一個行事曆的class定義和行程安排的介面interface。 請完成下列function 1.建構子MyCalendar() 初始化MyCalendar物件 2.boolean book(int start, int end) 插入新行程
Thumbnail
2024/09/10
Insert Greatest Common Divisors in Linked List 題目給定一個鏈結串列, 請在兩兩節點之間加入一個新節點,新節點的值為兩者之間的最大公因數。 最後返回新串列的head node作為答案。
Thumbnail
2024/09/10
Insert Greatest Common Divisors in Linked List 題目給定一個鏈結串列, 請在兩兩節點之間加入一個新節點,新節點的值為兩者之間的最大公因數。 最後返回新串列的head node作為答案。
Thumbnail
2024/09/09
2326. Spiral Matrix IV 題目給定一個Linked list和對應的矩陣高度m、寬度n。 請依照順時針的拜訪順序, 從左上角出發,依照次序把Linked List的內容填到矩陣裡。 如果有剩餘不足的空位,就填補-1。 最後將填補好的矩陣返回作為答案。
Thumbnail
2024/09/09
2326. Spiral Matrix IV 題目給定一個Linked list和對應的矩陣高度m、寬度n。 請依照順時針的拜訪順序, 從左上角出發,依照次序把Linked List的內容填到矩陣裡。 如果有剩餘不足的空位,就填補-1。 最後將填補好的矩陣返回作為答案。
Thumbnail
看更多
你可能也想看
Thumbnail
債券投資,不只是高資產族群的遊戲 在傳統的投資觀念中,海外債券(Overseas Bonds)常被貼上「高資產族群專屬」的標籤。過去動輒 1 萬甚至 10 萬美元的最低申購門檻,讓許多想尋求穩定配息的小資族望而卻步。 然而,在股市波動劇烈的環境下,尋求穩定的美元現金流與被動收入成為許多投資人
Thumbnail
債券投資,不只是高資產族群的遊戲 在傳統的投資觀念中,海外債券(Overseas Bonds)常被貼上「高資產族群專屬」的標籤。過去動輒 1 萬甚至 10 萬美元的最低申購門檻,讓許多想尋求穩定配息的小資族望而卻步。 然而,在股市波動劇烈的環境下,尋求穩定的美元現金流與被動收入成為許多投資人
Thumbnail
透過川普的近期債券交易揭露,探討債券作為資產配置中「穩定磐石」的重要性。文章分析降息對債券的潛在影響,以及股神巴菲特的操作策略。並介紹玉山證券「小額債」平臺,如何讓小資族也能低門檻參與海外債券市場,實現「低門檻、低波動、固定收益」的務實投資方式。
Thumbnail
透過川普的近期債券交易揭露,探討債券作為資產配置中「穩定磐石」的重要性。文章分析降息對債券的潛在影響,以及股神巴菲特的操作策略。並介紹玉山證券「小額債」平臺,如何讓小資族也能低門檻參與海外債券市場,實現「低門檻、低波動、固定收益」的務實投資方式。
Thumbnail
解析「債券」如何成為資產配置中的穩定錨,提供低風險高回報的投資選項。 藉由玉山證券的低門檻債券服務,投資者可輕鬆入手,平衡風險並穩定財務。
Thumbnail
解析「債券」如何成為資產配置中的穩定錨,提供低風險高回報的投資選項。 藉由玉山證券的低門檻債券服務,投資者可輕鬆入手,平衡風險並穩定財務。
Thumbnail
相較於波動較大的股票,債券能提供固定現金流,而玉山證券推出的小額債,更以1000 美元的低門檻,讓學生與新手也能參與全球優質企業債投資。玉山E-Trader平台即時報價、條件式篩選與清楚的交易流程等特色,大幅降低投資難度,對於希望分散風險、建立穩定現金流的人來說,玉山小額債是一個值得嘗試的理財起點。
Thumbnail
相較於波動較大的股票,債券能提供固定現金流,而玉山證券推出的小額債,更以1000 美元的低門檻,讓學生與新手也能參與全球優質企業債投資。玉山E-Trader平台即時報價、條件式篩選與清楚的交易流程等特色,大幅降低投資難度,對於希望分散風險、建立穩定現金流的人來說,玉山小額債是一個值得嘗試的理財起點。
Thumbnail
分享一個猜數字的遊戲題目,給予提示讓玩家找出正確的四位數密碼。
Thumbnail
分享一個猜數字的遊戲題目,給予提示讓玩家找出正確的四位數密碼。
Thumbnail
題目敘述 Single Number II 給定一個輸入陣列,已知有一個烙單的數字,其他剩餘的數字都恰巧出現三次。 請找出這個烙單的數字。 題目額外提出限制,請使用O(n)線性時間、O(1)常數空間複雜度的演算法。 測試範例 Example 1: Input: nums = [2,2,
Thumbnail
題目敘述 Single Number II 給定一個輸入陣列,已知有一個烙單的數字,其他剩餘的數字都恰巧出現三次。 請找出這個烙單的數字。 題目額外提出限制,請使用O(n)線性時間、O(1)常數空間複雜度的演算法。 測試範例 Example 1: Input: nums = [2,2,
Thumbnail
題目敘述 Single Number III 給定一個輸入陣列,已知有兩個烙單的數字,其他剩餘的數字都恰巧出現兩次。 請找出這兩個烙單的數字。 題目額外提出限制,請使用O(n)線性時間、O(1)常數空間複雜度的演算法。 測試範例 Example 1: Input: nums = [1,
Thumbnail
題目敘述 Single Number III 給定一個輸入陣列,已知有兩個烙單的數字,其他剩餘的數字都恰巧出現兩次。 請找出這兩個烙單的數字。 題目額外提出限制,請使用O(n)線性時間、O(1)常數空間複雜度的演算法。 測試範例 Example 1: Input: nums = [1,
Thumbnail
探討如何使用DP動態規劃的方法來進行單字串接,包含了DP遞迴關係式、狀態定義、優化技巧和程式碼示例。同時分析了時間複雜度、空間複雜度和關鍵知識點。這是LeetCode的一個應用題,類似於Word Break I的延伸。
Thumbnail
探討如何使用DP動態規劃的方法來進行單字串接,包含了DP遞迴關係式、狀態定義、優化技巧和程式碼示例。同時分析了時間複雜度、空間複雜度和關鍵知識點。這是LeetCode的一個應用題,類似於Word Break I的延伸。
Thumbnail
題目敘述 輸入給定一個鏈結串列的head node。 要求我們進行化簡,只要某個節點的右手邊存在比較大的節點,就刪除掉。 例如 5->2->13->3 5的右手邊有13,所以5刪除掉。 2的右手邊有13,所以2刪除掉。 13的右手邊沒有更大的節點,所以13留著。 3的右手邊沒有更大
Thumbnail
題目敘述 輸入給定一個鏈結串列的head node。 要求我們進行化簡,只要某個節點的右手邊存在比較大的節點,就刪除掉。 例如 5->2->13->3 5的右手邊有13,所以5刪除掉。 2的右手邊有13,所以2刪除掉。 13的右手邊沒有更大的節點,所以13留著。 3的右手邊沒有更大
Thumbnail
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給我們一個傳統手機的數字鍵盤 和一個數字鍵的輸入字串digits,要求我們列舉出所有輸入字串digits可能對應到的英文字母的排列。 例如輸入digits="23" 那對應到的英文字母排列就是"ad", "ae", "af", "bd", "be", "bf", "cd", "
Thumbnail
題目敘述 題目會給我們一個傳統手機的數字鍵盤 和一個數字鍵的輸入字串digits,要求我們列舉出所有輸入字串digits可能對應到的英文字母的排列。 例如輸入digits="23" 那對應到的英文字母排列就是"ad", "ae", "af", "bd", "be", "bf", "cd", "
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News