python - 力扣 752 : Open the Lock TLE with BFS

标签 python breadth-first-search

我正在尝试解决leetcode问题https://leetcode.com/problems/open-the-lock/与 BFS 并提出了下面的方法。

def openLock(self, deadends: List[str], target: str): -> int
      def getNeighbors(node) ->List[str]:
            neighbors = []
            dirs = [-1, 1]
            for i in range(len(node)):
                for direction in dirs:
                    x = (int(node[i]) + direction) % 10
                    neighbors.append(node[:i] + str(x) + node[i+1:])
            return neighbors
                        
        start = '0000'
        if start in deadends:
            return -1
        queue = deque()
        queue.append((start, 0))
        turns = 0
        visited = set()
        deadends = set(deadends)
        while queue:
            state, turns = queue.popleft()
            visited.add(state)
            if state == target:
                return turns
            for nb in getNeighbors(state):
                if nb not in visited and nb not in deadends:   
                    queue.append((nb, turns+1))
        return -1

但是此代码遇到了超出时间限制的异常,并且仅通过了 2/48 的测试用例。对于前。测试用例的死端为 ["8887","8889","8878","8898","8788","8988","7888","9888"] 和目标是“8888”(开头始终是“0000”)我的解决方案TLE。我注意到,如果我本质上更改一行并将相邻节点添加到我的内部循环中的访问集中,我的解决方案将通过该测试用例和所有其他测试用例。

for nb in getNeighbors(state):
     if nb not in visited and nb not in deadends:   
         visited.add(nb)
         queue.append((nb, turns+1))

我的 while 循环就变成了

while queue:
            state, turns = queue.popleft()
            if state == target:
                return turns
            for nb in getNeighbors(state):
                if nb not in visited and nb not in deadends:   
                    visited.add(nb)
                    queue.append((nb, turns+1))

有人可以解释为什么第一种方法会遇到 TLE 而第二种方法不会?

最佳答案

是的。绝对地。您需要在项目第一次添加到队列时将其添加到 visited 中,而不是在它从队列中删除时。否则你的队列将会呈指数级增长。

让我们看看 1111。您的代码会将 1000、0100、0010、0001(和其他)添加到队列中。然后,您的代码将添加 1100、1010、1001、0110、0101、0011 等两次,因为它们是队列中两个元素的邻居,并且尚未被访问过。然后将 1110、1101、1011、0111 各相加四次。如果您正在搜索 5555,您的队列中将会有很多重复项。

visited 变量的名称更改为 seen。请注意,一旦将某个项目放入队列中,就无需再次将其放入队列中。

说真的,尝试无死角地搜索 5555。当您找到它时,查看队列并查看队列中有多少元素,以及队列中有多少不同元素。

关于python - 力扣 752 : Open the Lock TLE with BFS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72918168/

相关文章:

python - 将图像发送到 CouchDb 两次而不是 1 次

python - 从python中的另一个列表构造一个列表

python | tkinter 和线程 : "main thread is not in main loop"

Python Scrapy - 需要动态 HTML、div 和 span 内容

haskell - 如何将列表一元函数转换为广度优先搜索?

algorithm - 具有循环依赖的 DFS

algorithm - 无法找到 spoj MMINPAID 的错误答案测试用例

python - 为什么将 np.nan 转换为 int 会产生巨大的数字?

python - 该算法的时间复杂度 : Word Ladder

c++ - 如何在boost中遍历图使用BFS