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

迷宫中离入口最近的出口:BFS解法超时优化求助

优化LeetCode「迷宫中离入口最近的出口」BFS超时问题

我在解决LeetCode的「迷宫中离入口最近的出口」问题时,选择了BFS算法(这确实是最优思路,因为BFS天然适合找最短路径),但处理大规模输入时出现了超时错误。以下是我的原实现代码:

def insidemaze(r,c,nrow,ncol,grid):
    if (( r>=0 and r<= nrow-1 and c>=0 and c<=ncol-1)) :
        return True
    return False    

def isboundary(r,c,nrow,ncol,grid):
    if ( r== 0 or r==nrow-1 or c== 0 or c==ncol-1) :
        return True 

class Solution:
    def nearestExit(self, maze: List[List[str]], entrance: List[int]) -> int:
        
        queue = collections.deque()
        queue.append([entrance[0],entrance[1],0])

        dirs = ((1, 0), (-1, 0), (0, 1), (0, -1))
        maze[entrance[0]][entrance[1]] = "+"

        nrow = len(maze)
        ncol = len(maze[0])

        while queue :
            print("queue =" , queue)
            a = queue.popleft()
            maze[a[0]][a[1]] = "+"
            for dir in dirs :
                b = [ a[0] + dir[0] , a[1] + dir[1] ]
                print("b=",b)
                if (insidemaze(b[0],b[1],nrow,ncol,maze) ) :
                    if (isboundary(b[0],b[1],nrow,ncol,maze) and (maze[b[0]][b[1]] == "." ) ) :
                        return(a[2]+1)
                    else :
                        if maze[b[0]][b[1]] == "." :
                            queue.append([b[0],b[1],a[2]+1])
                        else:
                            print("do nothing")    
        return(-1)

超时原因及优化方案

1. 移除调试打印语句

原代码中的print("queue =", queue)、print("b=",b)、print("do nothing")会在大规模输入时产生巨量IO操作,这是超时的主要原因之一,直接删除即可。

2. 内联判断逻辑,减少函数调用开销

单独的insidemaze和isboundary函数会带来额外的函数调用栈开销,尤其是在BFS循环中反复调用时,累积开销很大。可以直接将判断逻辑内联到代码中:

  • 入迷宫判断:0 <= nr < nrow and 0 <= nc < ncol
  • 边界判断:nr == 0 or nr == nrow-1 or nc == 0 or nc == ncol-1

3. 提前标记已访问节点,避免重复入队

原代码中,入口节点在入队前标记为已访问,但其他节点是在出队时才标记为"+"。这会导致同一个节点可能被多个邻居同时发现并加入队列,造成队列冗余,增加处理量。正确的做法是在入队前就标记该节点为已访问,确保每个节点只被处理一次。

4. 使用元组代替列表存储队列元素

元组比列表更轻量,访问速度更快,用元组存储队列中的坐标和步数,可以小幅提升性能。

优化后的代码

import collections
from typing import List

class Solution:
    def nearestExit(self, maze: List[List[str]], entrance: List[int]) -> int:
        queue = collections.deque()
        # 用元组存储队列元素
        queue.append((entrance[0], entrance[1], 0))
        dirs = ((1, 0), (-1, 0), (0, 1), (0, -1))
        nrow, ncol = len(maze), len(maze[0])
        # 入口标记为已访问
        maze[entrance[0]][entrance[1]] = "+"

        while queue:
            r, c, steps = queue.popleft()
            for dr, dc in dirs:
                nr, nc = r + dr, c + dc
                # 内联入迷宫判断
                if 0 <= nr < nrow and 0 <= nc < ncol:
                    if maze[nr][nc] == ".":
                        # 内联边界判断,入口已标记为+,不会误判为出口
                        if nr == 0 or nr == nrow-1 or nc == 0 or nc == ncol-1:
                            return steps + 1
                        # 入队前标记已访问,避免重复入队
                        maze[nr][nc] = "+"
                        queue.append((nr, nc, steps + 1))
        return -1

优化效果说明

  • 移除打印语句后,消除了IO瓶颈;
  • 内联判断减少了函数调用开销;
  • 提前标记已访问节点避免了队列冗余,大幅减少了BFS的循环次数;
  • 元组的使用进一步提升了内存和访问效率。

这些优化组合起来,能有效解决大规模输入下的超时问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 07:18:21