目录
[力扣733. 图像渲染](#力扣733. 图像渲染)
BFS解决FloodFill简介
FloodeFill算法即填充算法,中文:洪水灌溉,算法原理就是从一个点开始向四周扩散,向周围可以走到的点填充颜色,直到将可扩散到的点全部填充颜色。
通常使用下面两种方法解决FloodFill算法问题:
- BFS (宽搜)算法通常使用队列实现,将起始像素点加入队列中,并不断扩展队列中的像素点,直到队列为空为止。
- DFS(深搜) 算法通常使用递归实现,在处理当前像素点的相邻像素点时,递归调用 DFS 函数,不断深入直到无法找到相邻像素为止。
假设这一块4*4的方格是一块土地,有凸起的地方,也有凹陷的地方(凹陷的地方用负数表示)。此时下大雨发洪水,会把凹陷的地方填满。绿色圈起来的属于一块区域(上下左右四个方向,有时候题目也会问八个方向包括斜着相连的),题目会问有多少块区域被填满,或者问被填满的最大区域是哪个,或某一块区域的边长是多少。但是本质都是在一块区域找性质相同的连通块。
DFS:深度优先遍历(递归):从某一点开始一条路走到黑。以最右列的为例,从-1出发,向下->-2->-10->-12,此时发现-12的上下左右都走不了,在拐回去到-10,然后发现-10左边可以走->-4->-3。
BFS:宽度优先遍历:一层一层拨开。还是以最右边为例,从-1开始拓展一层(上下左右)发现能把-2扩展出来,接着继续扩展一层上下左右,-3和-10扩展出来;接着在扩展一层上下左右,把-4和-12扩展出来。
这时常用两个数组来遍历结点的上下左右结点:
cpp
int dx[4] = {0, 0 , -1, 1}; // i点加dx,dy就是i点的上下左右下标
int dy[4] = {1, -1 , 0, 0};
力扣733. 图像渲染
难度 简单
有一幅以 m x n
的二维整数数组表示的图画 image
,其中 image[i][j]
表示该图画的像素值大小。
你也被给予三个整数 sr
, sc
和 newColor
。你应该从像素 image[sr][sc]
开始对图像进行 上色填充 。
为了完成上色工作 ,从初始像素开始,记录初始坐标的 上下左右四个方向上 像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应 四个方向上 像素值与初始坐标相同的相连像素点,......,重复该过程。将所有有记录的像素点的颜色值改为 newColor
。
最后返回 经过上色渲染后的图像。
示例 1:
输入: image = [[1,1,1],[1,1,0],[1,0,1]],sr = 1, sc = 1, newColor = 2
输出: [[2,2,2],[2,2,0],[2,0,1]]
解析: 在图像的正中间,(坐标(sr,sc)=(1,1)),在路径上所有符合条件的像素点的颜色都被更改成2。
注意,右下角的像素没有更改为2,因为它不是在上下左右四个方向上与初始点相连的像素点。
示例 2:
输入: image = [[0,0,0],[0,0,0]], sr = 0, sc = 0, newColor = 2
输出: [[2,2,2],[2,2,2]]
提示:
m == image.length
n == image[i].length
1 <= m, n <= 50
0 <= image[i][j], newColor < 216
0 <= sr < m
0 <= sc < n
cpp
class Solution {
public:
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
}
};
解析代码
可以利用深搜或者宽搜,遍历到与该点相连的所有像素相同的点,然后将其修改成指定的像素即可。后面深搜专题用深搜写,这里用宽搜写:
cpp
class Solution {
int dx[4] = {0, 0 , -1, 1}; // i点加dx,dy就是i点的上下左右下标
int dy[4] = {1, -1 , 0, 0};
public:
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
int prev = image[sr][sc];
if(prev == color)
return image;
int m = image.size(), n = image[0].size(); // 获取大小防止越界
queue<pair<int, int>> q; // 存下标
q.push({sr, sc});
while(!q.empty()) // 模拟层序遍历
{
auto [a, b] = q.front(); // 拿到队头的元素(一个pair)
q.pop();
image[a][b] = color; // 拿到的元素染上新颜色
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 && image[x][y] == prev)
{
q.push({x, y});
}
}
}
return image;
}
};