这里提供两种实现,单向BFS和双向BFS。
python
class OpenLock:
"""
752. 打开转盘锁
https://leetcode.cn/problems/open-the-lock/
"""
def solution(self, deadends: List[str], target: str) -> int:
"""
单向BFS
:param deadends:
:param target:
:return:
"""
visited = set()
# 将deadends初始化到visited数组中
for deadend in deadends:
visited.add(deadend)
queue = []
step = 0
queue.append('0000')
visited.add('0000')
while queue:
sz = len(queue)
for i in range(sz):
cur = queue.pop(0)
if cur == target:
return step
if cur in visited:
continue
visited.add(cur)
for j in range(4):
up = self.plusOne(cur, j)
if up not in visited:
queue.append(up)
down = self.minusOne(cur, j)
if down not in visited:
queue.append(down)
step += 1
return -1
def plusOne(self, cur, j):
if cur[j] == '9':
return cur[:j] + '0' + cur[j+1:]
else:
return cur[:j] + str(int(cur[j])+1) + cur[j+1:]
def minusOne(self, cur, j):
if cur[j] == '0':
return cur[:j] + '9' + cur[j + 1:]
else:
return cur[:j] + str(int(cur[j]) - 1) + cur[j + 1:]
def solution2(self, deadends: List[str], target: str) -> int:
"""
双向BFS优化
:param deadends:
:param target:
:return:
"""
deads = set()
visited = set()
# 将deadends初始化到visited数组中
for deadend in deadends:
deads.add(deadend)
q1 = set()
q2 = set()
q1.add('0000')
q2.add(target)
step = 0
while q1 and q2:
# 额外优化
if len(q1) > len(q2):
tmp = q1
q1 = q2
q2 = tmp
temp = set()
for cur in q1:
if cur in deads:
continue
if cur in q2:
return step
visited.add(cur)
for j in range(4):
up = self.plusOne(cur, j)
if up not in visited:
temp.add(up)
down = self.minusOne(cur, j)
if down not in visited:
temp.add(down)
step += 1
# 这里temp相当于q1,交换q1和q2
q1 = q2
q2 = temp
return -1