echo

任生命穿梭 时间的角落

0%

图像渲染

733. 图像渲染

有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。

给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor,让你重新上色这幅图像。

为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。

最后返回经过上色渲染后的图像。

示例 1:

1
2
3
4
5
6
7
8
9
输入: 
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,
因为它不是在上下左右四个方向上与初始点相连的像素点。

注意:

  • imageimage[0] 的长度在范围 [1, 50] 内。
  • 给出的初始点将满足 0 <= sr < image.length0 <= sc < image[0].length
  • image[i][j]newColor 表示的颜色值在范围 [0, 65535]内。

方法一:DFS

我们从起点开始进行深度优先搜索,每搜索到一个方格时,如果它的颜色与初始位置的方格颜色相同,我们就将其颜色改为新的颜色,并继续搜索。

注意:在初始颜色和新颜色相同的情况下会造成死循环,仔细思考,这种情况不需要任何改变,直接返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
int m, n;
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
m = image.length;
n = image[0].length;

if(image[sr][sc] != newColor){
fill(image, image[sr][sc], newColor, sr, sc);
}
return image;
}

public void fill(int[][] image, int originColor, int newColor, int x, int y){
if(x < 0 || x >= m || y < 0 || y >= n || image[x][y] != originColor){
return;
}

image[x][y] = newColor;
fill(image, originColor, newColor, x + 1, y);
fill(image, originColor, newColor, x - 1, y);
fill(image, originColor, newColor, x, y + 1);
fill(image, originColor, newColor, x, y - 1);
}
}

时间复杂度O(mn),空间复杂度O(mn)。m 和 n 为图像的长宽。

方法二:BFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution {
int[] dx = new int[]{1, -1, 0, 0};
int[] dy = new int[]{0, 0, 1, -1};

public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
int originColor = image[sr][sc];
if(originColor == newColor){
return image;
}

int m = image.length, n = image[0].length;
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{sr, sc});

while(!queue.isEmpty()){
int[] point = queue.poll();
image[point[0]][point[1]] = newColor;

for(int i = 0; i < 4; i++){
int mx = point[0] + dx[i];
int my = point[1] + dy[i];

if(mx >= 0 && mx < m && my >= 0 && my < n && image[mx][my] == originColor){
queue.offer(new int[]{mx, my});
}
}
}

return image;
}

}

时间复杂度O(mn),空间复杂度O(mn)。m 和 n 为图像的长宽。