You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的BFS实现超时,而相似实现却能通过?

问题:LeetCode最短路径二进制矩阵BFS代码超时原因

我在解决LeetCode的最短路径二进制矩阵问题时,自己实现的BFS代码在大输入下超时(TLE),但另一版相似的代码却能通过测试,想知道是什么原因拖慢了我的代码。

我的代码:

class Solution:
    def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:

        if grid[0][0] == 1:
            return -1
        M=len(grid)-1
        seen = set()
        q = deque([])
        res = float('inf')
        q.append((0,0,1))

        while q:
            r,c, curr = q.popleft()
            if r==M and c==M:
                return curr
            directions = [[1,0], [0,1], [1,1], [-1,0], [0,-1], [-1,-1], [1, -1], [-1, 1]]
            seen.add((r,c))
            for ro, co in directions:
                nr, nc = r+ro, c+co
                if (nr,nc) in seen or nr < 0 or nc < 0 or nr > M or nc > M or grid[nr][nc] == 1:
                    continue
                q.append((nr,nc,curr+1))
        return -1

可以通过的相似代码:

class Solution:
    def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:
        N = len(grid)
        q = deque([(0, 0, 1)]) # r, c, length
        visit = set((0, 0))
        direct = [[0, 1], [1, 0], [0, -1], [-1, 0],
                  [1, 1], [-1, -1], [1, -1], [-1, 1]]
        while q:
            r, c, length = q.popleft()
            if (min(r, c) < 0 or max(r, c) >= N or
                grid[r][c]):
                continue
            if r == N - 1 and c == N - 1:
                return length
            for dr, dc in direct:
                if (r + dr, c + dc) not in visit:
                    q.append((r + dr, c + dc, length + 1))
                    visit.add((r + dr, c + dc))
        return -1
超时原因分析

你的代码超时主要有两个核心问题:

1. 已访问节点的标记时机错误

你的代码在出队后才将当前节点加入seen集合,这会导致同一个节点被多次加入队列。比如,当多个不同的邻居节点都能到达同一个未被标记的节点时,这些邻居都会把该节点重复添加到队列中,队列规模会迅速膨胀,后续需要处理大量重复节点,直接拖慢整体运行速度。

而通过的代码在入队前就将节点标记为已访问(visit.add((r + dr, c + dc))),每个节点只会被加入队列一次,从根源上避免了重复处理,这是性能差异的最关键原因。

2. 方向列表的重复创建

你把directions列表的定义放在了while循环内部,这意味着每次循环迭代都会重新创建这个包含8个元素的列表。虽然单次创建开销很小,但大网格场景下循环次数可能达到数万甚至数十万次,累积的额外内存分配和初始化开销会显著增加运行时间。

通过的代码将direct列表定义在循环外部,只创建一次,避免了重复创建的开销。

次要影响:边界与合法性检查的时机

你的代码在遍历邻居时才检查边界和网格值,而通过的代码在出队后先检查当前节点是否合法(比如越界或为1)。不过这个差异对性能的影响远小于前两点,属于可优化的细节。


内容的提问来源于stack exchange,提问作者paapipanda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 23:20:35