题目
给你一个 m x n 的迷宫矩阵 maze (下标从 0 开始),矩阵中有空格子(用 ‘.’ 表示)和墙(用 ‘+’ 表示)。同时给你迷宫的入口 entrance ,用 entrance = [entrancerow, entrancecol] 表示你一开始所在格子的行和列。 每一步操作,你可以往 上,下,左 或者 右 移动一个格子。你不能进入墙所在的格子,你也不能离开迷宫。你的目标是找到离 entrance 最近 的出口。出口 的含义是 maze 边界 上的 空格子。entrance 格子 不算 出口。 请你返回从 entrance 到最近出口的最短路径的 步数 ,如果不存在这样的路径,请你返回 -1 。
一、代码实现
func nearestExit ( maze [ ] [ ] byte , entrance [ ] int ) int { m := len ( maze) if m == 0 { return - 1 } n := len ( maze[ 0 ] ) if n == 0 { return - 1 } entranceRow, entranceCol := entrance[ 0 ] , entrance[ 1 ] queue := [ ] [ ] int { { entranceRow, entranceCol} } maze[ entranceRow] [ entranceCol] = '+' directions := [ ] [ ] int { { - 1 , 0 } , { 1 , 0 } , { 0 , - 1 } , { 0 , 1 } } steps := 0 for len ( queue) > 0 { levelSize := len ( queue) for i := 0 ; i < levelSize; i++ { cell := queue[ 0 ] queue = queue[ 1 : ] row, col := cell[ 0 ] , cell[ 1 ] for _ , dir := range directions { newRow := row + dir[ 0 ] newCol := col + dir[ 1 ] if newRow < 0 || newRow >= m || newCol < 0 || newCol >= n { continue } if maze[ newRow] [ newCol] == '+' { continue } if isExit ( newRow, newCol, entranceRow, entranceCol, m, n) { return steps + 1 } maze[ newRow] [ newCol] = '+' queue = append ( queue, [ ] int { newRow, newCol} ) } } steps++ } return - 1
} func isExit ( r, c, entranceR, entranceC, m, n int ) bool { return ( r == 0 || r == m- 1 || c == 0 || c == n- 1 ) && ! ( r == entranceR && c == entranceC)
}
二、算法分析
1. 核心思路
广度优先搜索(BFS) :从入口出发分层扩展,首次到达边界即最短路径出口判定 :当节点位于迷宫边界且非入口时视为合法出口状态管理 :使用二维数组记录访问状态,避免重复遍历
2. 关键步骤
队列初始化 :将入口位置加入队列,步数设为0分层遍历 :每次处理一层节点,检查是否符合出口条件方向扩展 :对合法相邻节点(非墙、未访问)进行入队终止条件 :队列为空时返回-1,表示无可行路径
3. 复杂度
指标 值 说明 时间复杂度 O(mn) 最坏情况遍历所有节点 空间复杂度 O(mn) 维护访问数组和队列的空间消耗
三、图解示例
四、边界条件与扩展
1. 特殊场景验证
入口即出口 :入口在边界但不算出口,需寻找其他边界点全封闭迷宫 :所有边界点均为墙,返回-1螺旋路径 :需绕行多层后到达边界出口
2. 扩展应用
动态障碍物 :支持实时更新墙的位置后重新计算路径多出口优化 :寻找所有出口中的最近/最远距离三维迷宫 :扩展为三维空间的路径搜索问题
3. 其他语言
from collections import dequedef nearestExit ( maze, entrance) : m, n = len ( maze) , len ( maze[ 0 ] ) directions = [ ( - 1 , 0 ) , ( 1 , 0 ) , ( 0 , - 1 ) , ( 0 , 1 ) ] visited = [ [ False ] * n for _ in range ( m) ] q = deque( ) ent_r, ent_c = entranceq. append( ( ent_r, ent_c, 0 ) ) visited[ ent_r] [ ent_c] = True while q: r, c, steps = q. popleft( ) if ( r == 0 or r == m- 1 or c == 0 or c == n- 1 ) and ( r, c) != ( ent_r, ent_c) : return stepsfor dr, dc in directions: nr, nc = r+ dr, c+ dcif 0 <= nr < m and 0 <= nc < n and not visited[ nr] [ nc] and maze[ nr] [ nc] == '.' : visited[ nr] [ nc] = True q. append( ( nr, nc, steps+ 1 ) ) return - 1
五、总结与优化
1. 方法对比
方法 优势 劣势 适用场景 BFS 保证最短路径 空间消耗较大 常规迷宫搜索 DFS 空间效率高 无法保证最短路径 路径存在性验证 A*算法 启发式搜索效率高 需设计启发函数 大型迷宫优化搜索
2. 工程优化
双向BFS :从入口和出口同时搜索,减少搜索空间压缩存储 :使用位运算压缩访问状态数组并行计算 :对多个方向进行并行路径探索
3. 算法扩展
权重迷宫 :不同路径消耗不同步数,寻找最小消耗路径移动模式 :支持对角线移动或限定转向次数动态规划 :预处理各点到边界的最短距离