有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。
给你一个坐标 (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, 因为它不是在上下左右四个方向上与初始点相连的像素点。
注意:
image
和image[0]
的长度在范围[1, 50]
内。- 给出的初始点将满足
0 <= sr < image.length
和0 <= sc < image[0].length
。 image[i][j]
和newColor
表示的颜色值在范围[0, 65535]
内。
思路:这道题可以用广搜和深搜来做
广搜:广搜我们需要一个记忆数组来保存哪些节点被访问过,以及一个辅助队列queue来对一个节点进行周边扩展,和基本的广搜的思路差不多,同时要注意的是边界条件控制(最上面,最左边,最下面,最右边)。
参考代码:
class Solution {
public:
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
int row = image.size(), column = image[0].size();
vector<vector<bool>> memo(image.size(), vector<bool>(image[0].size(),false));
queue<pair<int, int>> q;
q.push(make_pair(sr, sc));
memo[sr][sc] = true;
while (!q.empty()) {
int n = q.size();
for (int i = 0; i < n; i++) {
pair<int, int> tmp = q.front();
q.pop();
if (tmp.first > 0 && image[tmp.first - 1][tmp.second] == image[tmp.first][tmp.second]) {
if (memo[tmp.first - 1][tmp.second] == false) {
q.push(make_pair(tmp.first - 1, tmp.second));
memo[tmp.first - 1][tmp.second] = true;
}
}
if (tmp.first < (row - 1) && image[tmp.first + 1][tmp.second] == image[tmp.first][tmp.second]) {
if (memo[tmp.first + 1][tmp.second] == false) {
q.push(make_pair(tmp.first + 1, tmp.second));
memo[tmp.first + 1][tmp.second] = true;
}
}
if (tmp.second > 0 && image[tmp.first][tmp.second - 1] == image[tmp.first][tmp.second]) {
if (memo[tmp.first][tmp.second - 1] == false) {
q.push(make_pair(tmp.first, tmp.second - 1));
memo[tmp.first][tmp.second - 1] = true;
}
}
if (tmp.second < (column - 1) && image[tmp.first][tmp.second + 1] == image[tmp.first][tmp.second]) {
if (memo[tmp.first][tmp.second + 1] == false) {
q.push(make_pair(tmp.first, tmp.second + 1));
memo[tmp.first][tmp.second + 1] == true;
}
}
image[tmp.first][tmp.second] = newColor;
}
}
return image;
}
};
深搜,这里用了一个参数来替代记忆数组的作用,每次进入dfs的条件就是当前节点的颜色和初始化的旧颜色相同,这样可以避免使用记忆数组,同时也要注意边界控制。
参考代码:
class Solution {
public:
void dfs(vector<vector<int>>& image, int sr, int sc, int color, int newColor) {
if (image[sr][sc] == color) {
image[sr][sc] = newColor;
if (sr > 0) dfs(image, sr - 1, sc, color, newColor);
if ((sr+1) < image.size()) dfs(image, sr + 1, sc, color, newColor);
if (sc > 0) dfs(image, sr, sc-1, color, newColor);
if ((sc+1) < image[0].size()) dfs(image, sr, sc+1, color, newColor);
}
}
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
int color = image[sr][sc];
if(image[sr][sc] !=newColor) dfs(image, sr, sc, color, newColor);
return image;
}
};