752. Open Shortest Path wheel lock BFS

Do you have a turntable with four circular dial lock. Each dial has 10 digits: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'. Each dial may rotate freely: for example, the '9' to '0', '0' to '9'. Each rotation can only rotate the dial of a digit.

Lock initial number is '0000', a number of the dial string represents four.

Deadends list contains a set number of deaths, the same number and once any element in the list click wheel, the lock will be permanently locked and can no longer be rotated.

String target representatives can unlock digital, you need to give the minimum number of rotations, if any case can not unlock, returns -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
解释:
无法旋转到目标数字且不被锁定。
示例 4:

输入: deadends = ["0000"], target = "8888"
输出:-1
提示:

死亡列表 deadends 的长度范围为 [1, 500]。
目标数字 target 不会在 deadends 之中。
每个 deadends 和 target 中的字符串的数字会在 10,000 个可能的情况 '0000' 到 '9999' 中产生。
from collections import deque
# 最短路径
class Solution:
    def openLock(self, deadends: List[str], target: str) -> int:
        # 每次改变一位,-1或+1
        def neighbors(node):
            for i in range(4):
                inode = int(node[i])
                for j in (-1, 1):
                    x = (inode + j) % 10
                    yield node[:i] + str(x) + node[i + 1:]
        
        dead = set(deadends) # 将其变为集合,便于去重
        seen = set("0000")  # 转盘锁显示过的组合
        queue = deque([("0000", 0)])
        while queue:
            node, steps = queue.popleft()
            if node == target:
                return steps
            if node not in dead:
                for x in neighbors(node):
                    if x not in seen:
                        queue.append((x, steps + 1))
                        seen.add(x)
        return -1

Guess you like

Origin www.cnblogs.com/libbin/p/openLock.html