一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。
给你一个坐标 (sr, sc)
表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor
,让你重新上色这幅图像。
为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。
最后返回经过上色渲染后的图像。
首先获取图像的长和宽,以及初始值的颜色,如果初始值的颜色与newColor相同,那么我们无需进行渲染,直接返回图像,否则使用递归开始深度优先搜索,如果当前点的颜色与初始值相同的话,我们将当前的像素点渲染成新的颜色,然后使用递归对上下左右四个点深度优先搜索,然后调用深度优先搜索的函数,最后返回渲染后的图像
深度优先搜索
递归,这个到还好理解
class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
//获取初始坐标颜色
int color = image[sr][sc];
if(color!=newColor){//新颜色与初始颜色不同才调用函数
changes(image,sr,sc,color,newColor);
}
return image;//相同返回image
}
public void changes(int[][] image, int i, int j, int a,int newColor){
//传的位置要正确,行或列如果等于长,就越界,应该小于等于长,最后是判断位置的颜色,与初始颜色相同才改
//前四个条件就是搜索上下左右防止超出图像的
if(i<0||j<0||i==image.length||j==image[0].length||image[i][j]!=a){
return;
}
image[i][j] = newColor;//颜色修改
//调用递归
changes(image,i+1,j,a,newColor);//下
changes(image,i-1,j,a,newColor);//上
changes(image,i,j+1,a,newColor);//右
changes(image,i,j-1,a,newColor);//左
}
}
让我们再来看看官方题解,只是决定方向的方式不同,通过两个数组,顺序是下右左上
class Solution {
int[] dx = {1, 0, 0, -1};
int[] dy = {0, 1, -1, 0};
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
int currColor = image[sr][sc];
if (currColor != newColor) {
dfs(image, sr, sc, currColor, newColor);
}
return image;
}
public void dfs(int[][] image, int x, int y, int color, int newColor) {
if (image[x][y] == color) {
image[x][y] = newColor;
for (int i = 0; i < 4; i++) {
int mx = x + dx[i], my = y + dy[i];
if (mx >= 0 && mx < image.length && my >= 0 && my < image[0].length) {
dfs(image, mx, my, color, newColor);
}
}
}
}
}