一、题目

给定一个 m × n 的二维网格,网格中有以下三种可能的初始化值:

-1 表示墙或是障碍物
0 表示一扇门
INF 无限表示一个空的房间。然后,我们用 【LeetCode286】墙与门(BFS)_算法

你要给每个空房间位上填上该房间到 最近门的距离,如果无法到达门,则填 INF 即可。

【LeetCode286】墙与门(BFS)_BFS_02


样例1:

输入:
[[2147483647,-1,0,2147483647],[2147483647,2147483647,2147483647,-1],[2147483647,-1,2147483647,-1],[0,-1,2147483647,2147483647]]

输出:
[[3,-1,0,1],[2,2,1,-1],[1,-1,2,-1],[0,-1,3,4]]

解释:
2D网络为:
INF -1 0 INF
INF INF INF -1
INF -1 INF -1
0 -1 INF INF

答案为:
3 -1 0 1
2 2 1 -1
1 -1 2 -1
0 -1 3 4

【LeetCode286】墙与门(BFS)_初始化_03

二、思路

(1)先将所有门入队,从所有门开始BFS,入队的是点坐标,可以用​​pair​​​结构。
(2)入队时更新距离,而不是出队时,防止重复入队。
(3)更新的条件是​​​rooms[newx][newy] > rooms[x][y] + 1​​​,这里的​​rooms[x][y] + 1​​在本轮次(从该当前门开始BFS)遍历中本该属于该节点的树高度,如果这个高度(路径)更小自然就要更新了。

三、代码

class Solution {
private:
vector<pair<int, int>>directions{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
public:
void wallsAndGates(vector<vector<int>>& rooms) {
if(rooms.empty()){
return;
}
int row = rooms.size();
int col = rooms[0].size();
queue<pair<int, int>> q;
//先将所有门入队
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
if(rooms[i][j] == 0){
q.push(make_pair(i, j));
}
}
}
while(!q.empty()){
pair<int, int>a = q.front();
int x = a.first, y = a.second;
q.pop();
for(auto dir: directions){
int newx = x + dir.first, newy = y + dir.second;
if(isarea(rooms, newx, newy) && rooms[newx][newy] > rooms[x][y] + 1){
q.push(make_pair(newx, newy));
rooms[newx][newy] = rooms[x][y] + 1;
}
}
}
}
bool isarea(vector<vector<int>>&rooms, int x, int y){
return (x >= 0 && x < rooms.size() && y >= 0 && y < rooms[0].size());
}
};