No1:#### 286. 墙与门
难度:中
题目概述:矩阵中存在n个门,和m个墙,找到从门到墙的最短距离。墙是终点,门是起点
题解1:DFS
DFS的思路还是比较直白,一搜到底+做好剪枝
我比较意外的是,DFS居然没有超时,可见该题的性能测试的用例规模并不大。
class Solution {
public:
void wallsAndGates(vector>& rooms) {
for (int i = 0; i < rooms.size(); ++i) {
for (int j = 0; j < rooms[i].size(); ++j) {
if (rooms[i][j] == 0) dfs(rooms, i, j, 0);
}
}
}
void dfs(vector>& rooms, int i, int j, int step) {
if (i < 0 || i >= rooms.size() || j < 0 || j >= rooms[i].size() || rooms[i][j] < step) return;
rooms[i][j] = step;
dfs(rooms, i + 1, j, step + 1);
dfs(rooms, i - 1, j, step + 1);
dfs(rooms, i, j + 1, step + 1);
dfs(rooms, i, j - 1, step + 1);
}
};
题解2:BFS
由于需要记录每个门到墙的最小距离,而同一个门可能对多个点遍历到,所以再对于每一个坐标都需要记录其扩展步数(即在到达改点之前,已经做过多少步了),所以建立一个比较常用的数据对象queue
class Solution {
public:
vector> dir = {{1,0},{0,-1},{-1,0},{0,1}};
void wallsAndGates(vector>& rooms) {
queue>> q;
for (int i = 0; i < rooms.size(); ++i) {
for (int j = 0; j < rooms[i].size(); ++j) {
if (rooms[i][j] == 0) q.push({0, {i, j}});
}
}
int step = 0;
while(!q.empty()){
pair> cur = q.front(); q.pop();
cur.first++;
for (int i = 0; i < dir.size(); i++) {
int x = cur.second.first + dir[i][0];
int y = cur.second.second + dir[i][1];
if (x < 0 || x >= rooms.size() || y < 0 || y >= rooms[0].size() || rooms[x][y] < cur.first) continue;
rooms[x][y] = cur.first;
q.push({cur.first,{x, y}});
}
}
return;
}
};
这道题可以说是DFS和BFS最简单的模板题,在理解的基础上默写出模块是必须的。