题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flood-fill
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 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]内。
解决这个问题可以使用深度优先搜索遍历和广度优先搜索遍历
1. 方法一,深度优先遍历DFS
从初始坐标开始,把对应位置的值改为 newColor 然后递归执行其上、下、左、右四个方向的位置。唯一需要注意的就是当 newColor 和 image[sr][sc] 的值相等的话,则直接返回原image即可。下面给出代码
class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
//如果替换的值和原来的值一样,那么直接返回即可
if (image == null || image.length == 0 || image[sr][sc] == newColor) {
return image;
}
int target = image[sr][sc];
//从初始坐标开始尽心深度优先搜索遍历
dfs(image, sr, sc, newColor, target);
return image;
}
public void dfs(int[][] image, int r, int c, int newColor, int target) {
//如果越界或者对应的值和初始位置的初始值不一样,则直接返回
if (r < 0 || r >= image.length || c < 0 || c >= image[0].length ||image[r][c] != target) {
return;
}
//将当前位置的值改为newColor
image[r][c] = newColor;
//递归遍历上下左右
dfs(image, r + 1, c, newColor, target);
dfs(image, r - 1, c, newColor, target);
dfs(image, r, c + 1, newColor, target);
dfs(image, r, c - 1, newColor, target);
}
}
2. 方法二,广度优先遍历BFS
建立一个队列,先把初始位置的坐标加入,并把对应位置的值修改为 newColor ,然后把其 上下左右 中符合条件的坐标加入到队列中,然后重复此操作直到队列为空。
class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
//记录方向
int[] dx = {
1, 0, 0, -1};
int[] dy = {
0, 1, -1, 0};
//如果newColor和初始位置的值相等,直接返回原image
if (newColor == image[sr][sc]) {
return image;
}
//记录当前color
int currColor = image[sr][sc];
int rows = image.length, cols = image[0].length;
Queue<int[]> queue = new LinkedList<int[]>();
//先把初始位置加入队列中
queue.offer(new int[]{
sr, sc});
image[sr][sc] = newColor;
//进行广度优先搜索遍历
while (!queue.isEmpty()) {
int[] temp = queue.poll();
int x = temp[0], y = temp[1];
for (int i = 0; i < 4; i++) {
int mx = x + dx[i], my = y + dy[i];
if (mx >= 0 && mx < rows && my >= 0 && my < cols && image[mx][my] == currColor) {
queue.offer(new int[]{
mx, my});
image[mx][my] = newColor;
}
}
}
return image;
}
}