752. Open The Lock
MediumDescription
有一個四位數的密碼鎖,初始狀態為
"0000"。每次操作可以將某一位數字向上或向下轉動一格。給定一組deadends(死局狀態),求從"0000"到target的最少操作次數。若無法到達回傳-1。
Example:
Input: deadends = [“0201”,“0101”,“0102”,“1212”,“2002”], target = “0202” Output: 6
Intuition#
每個狀態有 8 個鄰居(4 位各可加減 1),用 BFS 找最短路徑。
- 將每個四位數字串視為圖的節點
- 每次轉動一位數字產生一個相鄰狀態
- 避開 deadends,BFS 找到 target 的最短步數
Approaches#
⭐1: BFS#
- 概念: 從 “0000” 開始 BFS,每步產生 8 個鄰居狀態,跳過 deadends
- 時間複雜度:
O(10^4 * 4),最多 10000 個狀態 - 空間複雜度:
O(10^4)
class Solution {
fun openLock(deadends: Array<String>, target: String): Int {
val dead = deadends.toHashSet()
if ("0000" in dead) return -1
if ("0000" == target) return 0
val visited = HashSet<String>()
visited.add("0000")
val queue = ArrayDeque<String>()
queue.add("0000")
var steps = 0
while (queue.isNotEmpty()) {
steps++
repeat(queue.size) {
val cur = queue.removeFirst()
for (i in 0 until 4) {
for (d in intArrayOf(-1, 1)) {
val arr = cur.toCharArray()
arr[i] = '0' + (arr[i] - '0' + d + 10) % 10
val next = String(arr)
if (next == target) return steps
if (next !in dead && next !in visited) {
visited.add(next)
queue.add(next)
}
}
}
}
}
return -1
}
}2: 雙向 BFS#
- 概念: 同時從起點和終點 BFS,每次擴展較小的一端,兩端相遇時即找到最短路徑
- 時間複雜度:
O(10^4 * 4)(實際更快) - 空間複雜度:
O(10^4)
class Solution {
fun openLock(deadends: Array<String>, target: String): Int {
val dead = deadends.toHashSet()
if ("0000" in dead || target in dead) return -1
if ("0000" == target) return 0
var beginSet = hashSetOf("0000")
var endSet = hashSetOf(target)
val visited = hashSetOf("0000", target)
var steps = 0
while (beginSet.isNotEmpty() && endSet.isNotEmpty()) {
steps++
if (beginSet.size > endSet.size) {
val tmp = beginSet; beginSet = endSet; endSet = tmp
}
val nextSet = HashSet<String>()
for (cur in beginSet) {
for (i in 0 until 4) {
for (d in intArrayOf(-1, 1)) {
val arr = cur.toCharArray()
arr[i] = '0' + (arr[i] - '0' + d + 10) % 10
val next = String(arr)
if (next in endSet) return steps
if (next !in dead && next !in visited) {
visited.add(next)
nextSet.add(next)
}
}
}
}
beginSet = nextSet
}
return -1
}
}🔑 Takeaways#
- Pattern: 隱式圖 BFS – 狀態空間搜尋最短路徑
- 關鍵技巧:
(digit + d + 10) % 10處理數字 0-9 的循環;雙向 BFS 可大幅減少搜尋空間