cpp
复制代码
class Solution
{
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& mat)
{
int n = mat.size(), m = mat[0].size();
vector<vector<int>> dist(n, vector<int>(m, -1));
queue<pair<int, int>> q;
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(mat[i][j] == 0)
{
dist[i][j] = 0;
q.push({i ,j});
}
}
}
while(q.size())
{
int sz = q.size();
while(sz--)
{
pair<int, int> p = q.front();
int a = p.first, b = p.second;
q.pop();
for(int i = 0; i < 4; i++)
{
int x = a + dx[i], y = b + dy[i];
if(x >= 0 && x < n && y >= 0 && y < m && dist[x][y] == -1)
{
dist[x][y] = dist[a][b] + 1;
q.push({x, y});
}
}
}
}
return dist;
}
};
// 从每个1开始BFS求最短路会超时
// 正难则反,可以求0到每个1的最短路,这样只需要记录这个1到0的最短路(用一个数组dist),当这个1BFS到下一个1时直接拿着这个1的最短路求下个1的最短路
cpp
复制代码
class Solution
{
public:
int numEnclaves(vector<vector<int>>& grid)
{
int n = grid.size(), m = grid[0].size();
queue<pair<int, int>> q;
vector<vector<bool>> vis(n, vector<bool>(m, false)); // 标记数组
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
int one_suma = 0; // 1的总个数
int one_sumb = 0; // 可以出界的1的总个数
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(grid[i][j] == 1)
{
one_suma++;
if(i == 0 || i == n - 1 || j == 0 || j == m - 1) // 边界
{
one_sumb++;
q.push({i, j});
vis[i][j] = true;
}
}
}
}
// BFS统计可以出界的1的个数
while(q.size())
{
auto [a, b] = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
int x = a + dx[i], y = b + dy[i];
if(x >= 0 && x < n && y >= 0 && y < m && !vis[x][y] && grid[x][y] == 1)
{
one_sumb++;
q.push({x, y});
vis[x][y] = true;
}
}
}
return one_suma - one_sumb;
}
};
// 先统计边界1,从边界1开始BFS,将可以出界的1全部标记一边即可
cpp
复制代码
class Solution
{
public:
vector<vector<int>> highestPeak(vector<vector<int>>& isWater)
{
int n = isWater.size(), m = isWater[0].size();
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
vector<vector<int>> dist(n, vector<int>(m, -1));
queue<pair<int, int>> q;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(isWater[i][j] == 1)
{
dist[i][j] = 0;
q.push({i, j});
}
}
}
while(q.size())
{
auto [a, b] = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
int x = a + dx[i], y = b + dy[i];
if(x >= 0 && x < n && y >= 0 && y < m && dist[x][y] == -1)
{
dist[x][y] = dist[a][b] + 1;
q.push({x, y});
}
}
}
return dist;
}
};
// 然后将0的下标全部入队列,进行多源BFS,每一次扩展加1,最终返回数组即可
cpp
复制代码
class Solution
{
public:
int maxDistance(vector<vector<int>>& grid)
{
int n = grid.size(), m = grid[0].size();
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
vector<vector<int>> dist(n, vector<int>(m, -1));
queue<pair<int, int>> q;
int sum1 = 0; // 1的数量是n*m或者0就直接返回-1
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(grid[i][j] == 1)
{
sum1++;
dist[i][j] = 0;
q.push({i, j});
}
}
}
if(sum1 == n * m || sum1 == 0) return -1;
int ret = 0;
while(q.size())
{
auto [a, b] = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
int x = a + dx[i], y = b + dy[i];
if(x >= 0 && x < n && y >= 0 && y < m && dist[x][y] == -1)
{
dist[x][y] = dist[a][b] + 1;
ret = max(ret, dist[x][y]);
q.push({x, y});
}
}
}
return ret;
}
};
// 从每个0BFS超时,反着来->正难则反。
// 从每个1开始多源BFS,找出最大的距离即可。
// 因为每次BFS碰到0都是1到这个0最近距离
// 用dist模拟距离即可