1.1介绍FloodFill问题
Floodfill问题的中文意思是洪水灌溉问题
上图
就根据这个图来讲解,洪水为1那么在洪水上下左右的数值如果小于1那么就会被覆盖即变成1
这个问题有很多方法解决,本文主要通过BFS(广度遍历)来解决,不想看BFS的可以起开了
1.2.BFS的介绍
BFS的概念:
广度优先搜索(也称宽度优先搜索,缩写BFS,以下采用广度来描述)是连通图的一种遍历策略。因为它的思想是从一个顶点开始,辐射状地优先遍历其周围较广的区域,因此得名。
一般可以用它做什么呢?一个最直观经典的例子就是走迷宫,我们从起点开始,找出到终点的最短路程,很多最短路径算法就是基于广度优先的思想成立的。
简单理解就是通过局部来完成对区域的搜索,下面通过例题来讲解
1.3.例题讲解
本题来自牛客网
题意还是很好理解的,就题目给你一个位置去找他旁边的相同颜色的位置将所有的相同颜色位置修改为color就可以了
1.4.开始编写代码
1.4.1.记录给定位置的颜色,并判断该位置的颜色与color是否相同,如果相同就返回原图像
创建一个队列来储存每一层的点的位置,用到了pair不懂的可以去了解一下,这个东西挺好用的
int beginc = image[sr][sc];
if(beginc == color) return image;
queue<pair<int ,int>> q;
int n = image.size();int m = image[0].size();
q.push({sr,sc});
1.4.2.层序遍历,找到符合条件的点
当队列不为空的时候,拿出队头的点并将该点的颜色修改,下面通过for循环来找到与对头相邻的点如果符合约束,就入队,重复该过程就结束了
while(!q.empty())
{
int a = q.front().first,b = q.front().second;q.pop();
image[a][b] = color;
for(int i = 0;i<4;i++)
{
int X = dx[i]+a,Y = dy[i]+b;
if(X>=0&&X<n&&Y>=0&&Y<m&&image[X][Y] == beginc)
{
q.push({X,Y});
}
}
}
1.4.3.完整代码
int dx[4] = {1,-1,0,0};
int dy[4] = {0,0,-1,1};
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
int beginc = image[sr][sc];
if(beginc == color) return image;
queue<pair<int ,int>> q;
int n = image.size();int m = image[0].size();
q.push({sr,sc});
while(!q.empty())
{
int a = q.front().first,b = q.front().second;q.pop();
image[a][b] = color;
for(int i = 0;i<4;i++)
{
int X = dx[i]+a,Y = dy[i]+b;
if(X>=0&&X<n&&Y>=0&&Y<m&&image[X][Y] == beginc)
{
q.push({X,Y});
}
}
}
return image;
}
2.1.介绍最短路径问题
上图
在图中,不可避免要解决的一个问题就是计算两点之间的最短路径,对于图结构来说,两个点之间不一定只有一条路径,那么如何才能找出最短的那一条就是图中最短路径问题。
这里介绍的是边权为1的最短路径问题,就相当于找到从最左端到最右端的最短距离
2.2.BFS解决逻辑
其实解决问题的逻辑就是开始时将起点记录,然后通过起点向后找到所有的起点可以一步达到的位置,并记录,对于记录这些点又同时找到他们可以一步到达的位置记录,然后重复,那么肯定有一个点先到终点。 上图好好看好好理解,我表述不清楚
2.3.讲解例题
先初始化,并将初始位置入队,vis图中标记初始位置
int dx[4] = {1,-1,0,0};
int dy[4] = {0,0,1,-1};
bool vis[100][100];
emset(vis, 0, sizeof vis);
int n = maze.size(),m = maze[0].size();
queue<pair<int ,int>> q;
int ret = 0;
q.push({entrance[0],entrance[1]}); vis[entrance[0]][entrance[1]] = true;
开始遍历,在内部要保证将原来队列里的点都输出后面的内容和上面的题差不多,就不过多唠叨
while(!q.empty())
{
ret++; int sz = q.size();
for(int j = 0;j<sz;j++)
{
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&&maze[x][y] == '.'&&vis[x][y] == false)
{
if(x == 0||x == n-1||y == 0||y == m-1)
return ret;
q.push({x,y});vis[x][y] = true;
}
}
}
}