1036. 逃 离 大 迷 宫 \color{red}{1036. 逃离大迷宫} 1036.逃离大迷宫
在一个 10^6 x 10^6 的网格中,每个网格上方格的坐标为 (x, y)
。
现在从源方格 source = [sx, sy]
开始出发,意图赶往目标方格 target = [tx, ty]
。数组 blocked
是封锁的方格列表,其中每个 blocked[i] = [xi, yi]
表示坐标为 (xi, yi)
的方格是禁止通行的。
每次移动,都可以走到网格中在四个方向上相邻的方格,只要该方格 不 在给出的封锁列表 blocked
上。同时,不允许走出网格。
只有在可以通过一系列的移动从源方格 source
到达目标方格 target
时才返回 true
。否则,返回 false
。
数据(关键)约束:
0 <= blocked.length <= 200
解题思路:
- 首先对于这种网格中找路径的问题,一般都是通过搜索算法解题——根据是否要求最短路径,数据量大小等酌情选取DFS或者BFS,以及其他更优的搜索算法…
- 由于这道题的数据量,而且没有要求找一条最短的“逃脱”路径,如果通过BFS逐步扩展的话肯定没机会的;考虑一下DFS,在根据这道题的Hard难度,不难想到使用优化后的DFS算法——最常见的优化就是剪枝优化了(常用剪枝策略有三种:记忆化-相同值从记忆数组中提取结果、最优解判断-如果当前枝差于当前最优剪枝、可行性剪枝-当前枝不可能获得解剪枝)
- 但是这道题应该不是剪枝,而属于距离限制的DFS搜索:由于一个特殊的数据约束,封锁格子最多只有200格,假设这些格子按照斜线排序达到最好封锁效果,类似与如下边,只要DFS到达的点和原点的曼哈顿距离到达一定范围,即肯定冲破封锁。这个范围根据最好的封锁效果(图1)不难得到为blocked.length
- 于是,在DFS达到据原点一定距离的点,或者直接搜索到目标,即表示该节点“free”了
解题代码:
还有很大改进空间:
class Solution {
//封锁格子数量
int len;
//上下左右方向数组
int[][] d;
//保存访问信息
Map<Integer,Set<Integer>> v;
//全局block
int[][] b;
public boolean isEscapePossible(int[][