你有乙個帶有四個圓形撥輪的轉盤鎖。每個撥輪都有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」示例2:輸出:6
解釋:可能的移動序列為 「0000」 -> 「1000」 -> 「1100」 -> 「1200」 -> 「1201」 -> 「1202」 -> 「0202」。
注意 「0000」 -> 「0001」 -> 「0002」 -> 「0102」 -> 「0202」 這樣的序列是不能解鎖的,
因為當撥動到 「0102」 時這個鎖就會被鎖定。
輸入: deadends = [「8888」], target = 「0009」示例3:輸出:1
解釋:把最後一位反向旋轉一次即可 「0000」 -> 「0009」。
輸入: 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...