
上篇我们介绍了多源BFS的相关背景知识,本篇我们将结合具体题目分析,进一步深化对于BFS算法的理解运用。
返回的矩阵中,原来为0的节点,保持为0即可,而原来为1的节点,则指应修改为到最近的0的距离
正难则反的思想,把0当作起点,求取最近的1这是由于我们把1当作起点进行遍历时,需要统计存储多条路径,在进行比较时较为繁琐
class Solution {
public:
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
int m=mat.size(),n=mat[0].size();
//全部初始化为-1,表示尚未计算出最短路径
vector<vector<int>> dis(m,vector<int>(n,-1));
queue<pair<int,int>> q;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(mat[i][j]==0)
{
dis[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<m && y>=0 && y<n && dis[x][y]==-1)
{
q.push({x,y});
dis[x][y]=dis[a][b]+1;//步数加1
}
}
}
return dis;
}
};乍一看会感觉无从下手,找不出与多源bfs算法的关系,但如果同样采取正难则反的思想,就迎刃而解了:
class Solution {
public:
int dx[4] = { 0,0,-1,1 };
int dy[4] = { 1,-1,0,0 };
int numEnclaves(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
vector<vector<bool>> vis(m, vector<bool>(n));//标记数组
queue<pair<int, int>> q;
//先将边界的1入队列
for (int i = 0; i < m; i++)
{
if (grid[i][0] == 1)
{
q.push({ i,0 });
vis[i][0] = true;
}
if (grid[i][n - 1] == 1)
{
q.push({ i,n - 1 });
vis[i][n - 1] = true;
}
}
for (int j = 0; j < n; j++)
{
if (grid[0][j] == 1)
{
q.push({ 0,j });
vis[0][j] = true;
}
if (grid[m - 1][j] == 1)
{
q.push({ m - 1,j });
vis[m - 1][j] = true;
}
}
//多源bfs
while (q.size())
{
auto [a, b] = q.front();
q.pop();
vis[a][b] = true;
for (int i = 0; i < 4; i++)
{
int x = a + dx[i], y = b + dy[i];
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && !vis[x][y])
{
q.push({ x,y });
vis[x][y] = true;
}
}
}
//统计结果
int ret = 0;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (grid[i][j] == 1 && vis[i][j] == false)
{
ret++;
}
}
}
return ret;
}
};陆地 和 水域 单元格组成的地图。如果 isWater[i][j] == 0 ,格子 (i, j) 是一个
陆地格子。 如果 isWater[i][j] == 1 ,格子(i, j) 是一个水域格子。
水域的高度必须为0,相邻的格子之间高度差最大为1本题与01矩阵类似,我们只需要把遍历矩阵,将所有水域入队列,之后在bfs遍历过程中,将相邻的陆地高度更新为dis[x][y]=dis[a][b]+1即可
class Solution {
public:
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
vector<vector<int>> highestPeak(vector<vector<int>>& isWater) {
int m=isWater.size(),n=isWater[0].size();
vector<vector<int>> dis(m,vector<int>(n,-1));//返回数组
queue<pair<int,int>> q;
//将水域入队列
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(isWater[i][j]==1)
{
q.push({i,j});
dis[i][j]=0;//水域的高度为0
}
}
}
while(q.size())
{
int sz=q.size();
while(sz--)
{
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<m && y>=0 && y<n && !isWater[x][y] && dis[x][y]==-1)//条件为不越界并且为陆地且为被遍历过
{
q.push({x,y});
dis[x][y]=dis[a][b]+1;
}
}
}
}
return dis;
}
};class Solution {
public:
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
int m,n;
int ret=-1;//最大高度
int maxDistance(vector<vector<int>>& grid) {
m=grid.size(),n=grid[0].size();
vector<vector<int>> dis(m,vector<int>(n,-1)) ;
queue<pair<int,int>> q;
//将陆地入队列
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(grid[i][j]==1)
{
dis[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<m && y>=0 && y<n && grid[x][y]==0 && dis[x][y]==-1)
{
q.push({x,y});
dis[x][y]=dis[a][b]+1;
ret=max(ret,dis[x][y]);//更新高度
}
}
}
return ret;
}
};本篇关于多源bfs的介绍就暂告段落啦,希望能对大家的学习产生帮助,欢迎各位佬前来支持斧正!!!