Leetcode752 開啟轉盤鎖詳細題解

2021-10-23 14:43:26 字數 3064 閱讀 3989

你有乙個帶有四個圓形撥輪的轉盤鎖。每個撥輪都有10個數字: 『0』, 『1』, 『2』, 『3』, 『4』, 『5』, 『6』, 『7』, 『8』, 『9』 。每個撥輪可以自由旋**例如把 『9』 變為  『0』,『0』 變為 『9』 。每次旋轉都只能旋轉乙個撥輪的一位數字。

鎖的初始數字為 『0000』 ,乙個代表四個撥輪的數字的字串。

列表 deadends 包含了一組死亡數字,一旦撥輪的數字和列表裡的任何乙個元素相同,這個鎖將會被永久鎖定,無法再被旋轉。

字串 target 代表可以解鎖的數字,你需要給出最小的旋轉次數,如果無論如何不能解鎖,返回 -1。

示例1:

輸入:deadends = [「0201」,「0101」,「0102」,「1212」,「2002」], target = 「0202」

輸出:6

解釋:可能的移動序列為 「0000」 -> 「1000」 -> 「1100」 -> 「1200」 -> 「1201」 -> 「1202」 -> 「0202」。

注意 「0000」 -> 「0001」 -> 「0002」 -> 「0102」 -> 「0202」 這樣的序列是不能解鎖的,

因為當撥動到 「0102」 時這個鎖就會被鎖定。

示例2:

輸入: deadends = [「8888」], target = 「0009」

輸出:1

解釋:把最後一位反向旋轉一次即可 「0000」 -> 「0009」。

示例3:

輸入: deadends = [「8887」,「8889」,「8878」,「8898」,「8788」,「8988」,「7888」,「9888」], target = 「8888」

輸出:-1

解釋:無法旋轉到目標數字且不被鎖定。

廣度優先搜尋

可以把這道題看成乙個找出圖中最短路徑的問題。每個節點都是棋盤的乙個狀態,如果兩個狀態之間可以通過一步操作來完成轉換,就用一條邊將這兩個節點相連。用廣度優先搜尋來解決最短路徑問題。

演算法在廣度優先搜尋實現中,需要將節點表示成可以雜湊的資料結構,同時還需要找到每個節點的鄰居節點。之後套乙個下面這樣的廣度優先搜尋模板就可以了。

// 計算從起點 start 到終點 target 的最近距離

intbfs

(node start, node target)

}/* 劃重點:更新步數在這裡 */

step++;}

}

關鍵是問題的轉化:

1 將鎖轉化為圖的問題:每個狀態都是乙個節點

2 將每一次的撥動看成尋找鄰接節點:每一次的撥動共有8種方法(4個數字上撥/下撥),即有8個鄰接節點。

3 狀態之間的轉化可以用一條邊將兩個節點相連,由此構建出來的搜尋樹

###參考**

public

class

open_the_lock_752

// 到達終點

if(curnumber.

equals

(target)

)// 將節點的未遍歷的相鄰節點加入佇列

for(

int j =

0; j < password_length; j++

) string downone =

downone

(curnumber, j);if

(!visited.

contains

(downone))}

} step++;}

// 無解

return-1

;}/** * 向上撥動一位數字

** @param curnumber 當前的密碼

* @param i 撥動第幾位

* @return 撥動後的數字

*/private string upone

(string curnumber,

int i)

else

return

newstring

(ch);}

/** * 向下撥動一位數字

** @param curnumber 當前的密碼

* @param i 撥動第幾位

* @return 撥動後的數字

*/private string downone

(string curnumber,

int i)

else

return

newstring

(ch);}

}

/**

* 雙向bfs

** @param deadends

* @param target

* @return

*/public

intopenlock

(string[

] deadends, string target)

// 到達終點

if(q2.

contains

(curnumber)

)// 記錄

visited.

add(curnumber)

;// 將節點的未遍歷的相鄰節點加入佇列

for(

int j =

0; j < password_length; j++

) string downone =

downone

(curnumber, j);if

(!visited.

contains

(downone))}

} step++

;// temp 相當於 q1

// 這裡交換 q1 q2,下一輪 while 就是擴散 q2

q1 = q2;

q2 = tmp;

}// 無解

return-1

;}

leetcode 752 開啟轉盤鎖

752.開啟轉盤鎖 你有乙個帶有四個圓形撥輪的轉盤鎖。每個撥輪都有10個數字 0 1 2 3 4 5 6 7 8 9 每個撥輪可以自由旋 例如把 9 變為 0 0 變為 9 每次旋轉都只能旋轉乙個撥輪的一位數字。鎖的初始數字為 0000 乙個代表四個撥輪的數字的字串。列表 deadends 包含了一...

開啟轉盤鎖(LeetCode 752)

你有乙個帶有四個圓形撥輪的轉盤鎖。每個撥輪都有10個數字 0 1 2 3 4 5 6 7 8 9 每個撥輪可以自由旋 例如把 9 變為 0 0 變為 9 每次旋轉都只能旋轉乙個撥輪的一位數字。鎖的初始數字為 0000 乙個代表四個撥輪的數字的字串。列表 deadends 包含了一組死亡數字,一旦撥輪...

leetcode 752 開啟轉盤鎖

目錄你的鼓勵也是我創作的動力 你有乙個帶有四個圓形撥輪的轉盤鎖。每個撥輪都有10個數字 0 1 2 3 4 5 6 7 8 9 每個撥輪可以自由旋 例如把 9 變為 0 0 變為 9 每次旋轉都只能旋轉乙個撥輪的一位數字。鎖的初始數字為 0000 乙個代表四個撥輪的數字的字串。列表 deadends...