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
0 <= xi, yi < 10^6来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/escape-a-large-maze
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
- 分析规律
- 不能遍历所有网格,要找捷径
- 封锁的方格最多只有200个,从这里突破
- 无法到达的情况只有起点或终点被包住时
- 若起点或终点可达的点大于可能围成的最大面积,则可通行
- 解题
- bfs计算可达的点的数量
- 注意:若找到对方则也可达;bfs过程中要更新
vis
class Solution {
public:
bool isEscapePossible(vector<vector<int>>& blocked, vector<int>& source, vector<int>& target) {
set<pair<int, int>> bset;
for(auto& p : blocked) bset.insert({p[0], p[1]});
int n = blocked.size();
int maxc = n * (n - 1) / 2 + 1;
// 分别计算起点和终点是否可达的点超过最大值或是否可达到对方
return check(source, maxc, bset, target) && check(target, maxc, bset, source);
}
bool check(const vector<int>& node, const int& maxc, const set<pair<int, int>>& bset, const vector<int>& bnode)
{
int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
set<pair<int, int>> vis;
queue<pair<int, int>> q;
vis.insert({node[0], node[1]});
q.push({node[0], node[1]});
int count = 0;
while(q.size())
{
auto ver = q.front();
q.pop();
count++;
if(count > maxc) return true;
// 找到对方时也可达
if(ver.first == bnode[0] && ver.second == bnode[1]) return true;
for(int i = 0; i < 4; i++)
{
int x = ver.first + dx[i], y = ver.second + dy[i];
if(x < 0 || x >= 1e6 || y < 0 || y >= 1e6) continue;
if(bset.count({x, y}) || vis.count({x, y})) continue;
q.push({x, y});
// 记得更新vis
vis.insert({x, y});
}
}
return false;
}
};

浙公网安备 33010602011771号