一、题目
编写函数,实现许多图片编辑软件都支持的「颜色填充」功能。
待填充的图像用二维数组 image 表示,元素为初始颜色值。初始坐标点的行坐标为 sr 列坐标为 sc。需要填充的新颜色为 newColor 。
「周围区域」是指颜色相同且在上、下、左、右四个方向上存在相连情况的若干元素。
请用新颜色填充初始坐标点的周围区域,并返回填充后的图像。
二、解析
经典的DFS题目,基本都是按着上,下,左,右遍历,直接上代码
三、代码
3.1 最简洁的DFS
class Solution {
public:
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
int oldColor = image[sr][sc]; //记录旧坐标的像素
if (image[sr][sc] == newColor) return image; //颜色相同则无需修改
image[sr][sc] = newColor; //染色
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; //上右下左
for (int i = 0; i < 4; i ++) {
int x = sr + dx[i], y = sc + dy[i];
if (x >=0 && y >= 0 && x < image.size() && y < image[0].size() && image[x][y] == oldColor)
floodFill (image, x, y, newColor);
}
return image;
}
};
3.2 使用二维数组记录的DFS
class Solution {
public:
int m_src = 0;
void dfs(vector<vector<int>> &grid,vector<vector<int>>& visit , int cur_i, int cur_j, int newColor)
{
// 边界条件(包括超过数组范围,以及当前不为1)
if (cur_i < 0 || cur_j < 0 || cur_i == grid.size() || cur_j == grid[0].size()) {
return;
}
if (visit[cur_i][cur_j]) {
return;
}
visit[cur_i][cur_j] = 1; // 访问过,置1
int di[4] = {0, 0, 1, -1};
int dj[4] = {1, -1, 0, 0};
if (grid[cur_i][cur_j] == m_src) {
grid[cur_i][cur_j] = newColor;
for (int index = 0; index != 4; ++index) {
int next_i = cur_i + di[index], next_j = cur_j + dj[index]; // 下一个位置
dfs(grid, visit, next_i, next_j, newColor);
}
}
}
vector<vector<int>> floodFill(vector<vector<int>> &image, int sr, int sc, int newColor)
{
int rows = image.size();
int cols = image[0].size();
if (rows == 0 || cols == 0) {
return {};
}
m_src = image[sr][sc]; // 记录目标值
vector<vector<int>> visited(rows,vector<int>(cols,0)); // 定义一个标记数组
dfs(image,visited, sr, sc, newColor);
return image;
}
};
3.3 最常使用DFS
class Solution {
public:
void dfs(vector<vector<int>> &image, int sr, int sc, int newColor, int oldColor)
{
if (sr < 0 || sc < 0 || sr >= image.size() || sc >= image[0].size()) {
return; // 边界条件
}
int di[4] = {0, 0, 1, -1};
int dj[4] = {1, -1, 0, 0};
if (image[sr][sc] == oldColor && image[sr][sc] != newColor) {
image[sr][sc] = newColor; // 从新赋值
for (int index = 0; index != 4; ++index) {
int next_i = sr + di[index], next_j = sc + dj[index]; // 下一个位置
dfs(image, next_i, next_j, newColor,oldColor);
}
}
};
vector<vector<int>> floodFill(vector<vector<int>> &image, int sr, int sc, int newColor)
{
int oldColor = image[sr][sc]; //记录旧坐标的像素
dfs(image, sr, sc, newColor, oldColor);
return image;
}
};
3.4 经典的BFS
class Solution {
public:
vector<vector<int>> floodFill(vector<vector<int>> &image, int sr, int sc, int newColor)
{
int oldColor = image[sr][sc]; //记录旧坐标的像素
queue<pair<int, int>> queuei;
int di[4] = {0, 0, 1, -1};
int dj[4] = {1, -1, 0, 0};
queuei.push(make_pair(sr, sc));
while (!queuei.empty()) {
int cur_i = queuei.front().first; // 取出当前的土地的坐标
int cur_j = queuei.front().second;
queuei.pop();
if (cur_i < 0 || cur_j < 0 || cur_i >= image.size() || cur_j >= image[0].size()) {
continue; // 边界条件
}
if (image[cur_i][cur_j] == oldColor && image[cur_i][cur_j] != newColor) {
for (int index = 0; index != 4; ++index) {
int next_i = cur_i + di[index], next_j = cur_j + dj[index]; // 下一个位置
queuei.push(make_pair(next_i, next_j));
}
image[cur_i][cur_j] = newColor; // 重新赋值
}
}
return image;
}
};
参考: