①.问题描述: 在一个 N × M 的竞技场迷宫中,找出在迷宫中,所有"危险位置"的数量。"危险位置"定义为:如果站在该位置上,无论采取什么移动策略,都无法到达出口。 竞技场中包含以下几种元素:
-
.:表示普通地板,可以自由移动到上下左右相邻的格子(不可以走斜线) -
O:表示出口 -
U:表示向上的传送器,踩上去会被强制传送到上方的格子 -
D:表示向下的传送器,踩上去会被强制传送到下方的格子 -
L:表示向左的传送器,踩上去会被强制传送到左方的格子 -
R:表示向右的传送器,踩上去会被强制传送到右方的格子注意,如果被传送出了竞技场之外,则算作死亡。
②.想法思路:
输入:N: 一个整数,表示竞技场地图的行数;M: 一个整数,表示竞技场地图的列数;data: 一个字符二维数组,表示竞技场地板地图。数组大小为 N × M,其中 1 ≤ N, M ≤ 100。
输出:“危险位置”的数量
考虑采用DFS算法来解决这一问题。主要步骤如下:
1.方向映射,定义了上下左右的方向增量:
2.检查坐标(x, y)是否在迷宫范围内。
3.递归函数,判断从某个起点(start_x, start_y)是否能够到达出口。
3.1 越界检查
3.2 环检查
3.3 检查是否到达出口
3.4 标记当前位置
3.5 处理传送点:如果当前点是传送点(值为'U', 'D', 'L', 'R'之一),则根据directions计算下一步的坐标(next_x, next_y),递归检查下一位置是否能到达出口。
3.6 普通点的四方向尝试:如果当前位置不是传送点,尝试向上下左右四个方向移动,递归调用can_reach_exit:对每个方向计算新的坐标(next_x, next_y)。检查新位置是否合法,并递归调用。如果任意方向能够到达出口,则返回True。每次递归调用时,visited集合会通过copy创建副本,避免影响其他递归分支。
3.7 计算“危险位置”数量
③总结分析
1.复杂度分析
时间复杂度:
- 迷宫遍历:每个位置最多访问一次,复杂度为
O(N × M)。 - 递归调用:每次递归最多探索四个方向,复杂度近似
O(N × M × 4)。 - 总体复杂度约为
O(N × M)。
空间复杂度:
- 使用集合
visited记录访问的节点,空间复杂度为O(N × M)。