返回
转动开锁——广度优先搜索的妙用
前端
2024-02-21 03:12:03
转动开锁——别出心裁的密码挑战
设想这样一个情境:您置身于一个房间,面前有一扇转盘锁,四个圆形拨轮紧密相扣,阻挡了您的去路。每个拨轮上有 10 个数字,从 0 到 9,您需要通过转动拨轮,使它们排列成特定的顺序,才能打开锁。
广度优先搜索——抽丝剥茧的探索之道
广度优先搜索(BFS)是一种算法,它从图的根节点开始,一层一层地探索图的各个节点。在 BFS 中,所有同一层级的节点都会在同一时间被访问,然后才会继续探索下一层的节点。
在「752. 打开转盘锁」中,我们可以将转盘锁的状态视为一个图,图中的每个节点表示一种可能的转盘锁状态,而图中的每条边表示从一种状态到另一种状态的转换。
广度优先搜索从初始状态开始,将所有相邻状态加入队列,然后依次访问这些状态。如果某个相邻状态是目标状态,那么搜索结束;否则,将该状态的所有相邻状态加入队列,继续搜索。
模运算——环环相扣的数字世界
在「752. 打开转盘锁」中,转盘锁的每个拨轮上有 10 个数字,从 0 到 9。当某个拨轮转动到 9 后,再转动一次就会回到 0。同理,当某个拨轮转动到 0 后,再转动一次就会回到 9。
这种数字的循环特性可以用模运算来表示。模运算是一种数学运算,它可以计算两个数相除后的余数。在「752. 打开转盘锁」中,我们可以使用模运算来计算转盘锁的每个拨轮在转动后所处的状态。
算法实现——步步为营的探索之旅
def openLock(deadends, target):
# 初始化队列和已访问状态集合
queue = [(0, 0, 0, 0)]
visited = set()
# 广度优先搜索
while queue:
# 从队列中取出当前状态
state = queue.pop(0)
# 如果当前状态是目标状态,则返回步数
if state == target:
return steps
# 将当前状态加入已访问状态集合
visited.add(state)
# 遍历当前状态的四个拨轮
for i in range(4):
# 将当前拨轮向左转动一位
new_state = (state[i] - 1) % 10
# 将当前拨轮向右转动一位
new_state = (state[i] + 1) % 10
# 如果新状态不在已访问状态集合中,则将其加入队列
if new_state not in visited:
queue.append(new_state)
# 如果没有找到目标状态,则返回 -1
return -1
结语
广度优先搜索算法以其简单易懂的实现方式,为解决图论问题提供了高效而强大的工具。「752. 打开转盘锁」一题巧妙地融合了广度优先搜索和模运算,为我们展示了算法在解决实际问题中的应用魅力。