图像渲染
有一幅以 m x n 的二维整数数组表示的图画 image ,其中 image[i][j] 表示该图画的像素值大小。
你也被给予三个整数 sr , sc 和 newColor 。你应该从像素 image[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,因为它不是在上下左右四个方向上与初始点相连的像素点。
示例 2:
输入: image = [[0,0,0],[0,0,0]], sr = 0, sc = 0, newColor = 2
输出: [[2,2,2],[2,2,2]]
(上述题目来源于LeetCode)
解法一(深度优先搜索–DFS)
class Solution {
//深度优先搜索
public void fill(int[][] image,int sr,int sc,int oldColor,int newColor){
int row = image.length;
int column = image[0].length;
//如果行数列数小于0或者行数列数已经达到最大值或者图像元素不相连都直接跳出
if(sr < 0 || sr == row || sc < 0 || sc == column || image[sr][sc] != oldColor){
return;
}
//改变颜色
image[sr][sc] = newColor;
//递归遍历图像元素
fill(image,sr - 1,sc,oldColor,newColor);
fill(image,sr + 1,sc,oldColor,newColor);
fill(image,sr,sc - 1,oldColor,newColor);
fill(image,sr,sc + 1,oldColor,newColor);
}
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
int oldColor = image[sr][sc];
//如果新老颜色相同,则不需要改变颜色
if(oldColor != newColor){
fill(image,sr,sc,oldColor,newColor);
}
return image;
}
}
解法二(广度优先搜索–BFS)
class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
//广度优先搜索(BFS)
//定义元素分别向上、下、左、右四个方向移动
int[] dx = {-1,1,0,0};
int[] dy = {0,0,-1,1};
//如果新老颜色相同,则图像不会发生改变
int oldColor = image[sr][sc];
if(oldColor == newColor){
return image;
}
//用LinkedList实现队列,队列用来存储图像元素的坐标
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{sr,sc});
//先将第一个点作为广度优先搜素的第一层,上色
image[sr][sc] = newColor;
//再将向上下左右四个方向作为广度优先搜索的第二层
while(queue.isEmpty() == false){
//分解元素
int[] cell = queue.remove();
int cx = cell[0];
int cy = cell[1];
//向上下左右四个方向搜索
for(int i = 0;i < 4;i++){
int x = cx + dx[i];
int y = cy + dy[i];
//如果满足条件,对其上色,并将上色以后的点的坐标加入到队列中
//在队列不为空的情况下,队列将一直移除点的坐标,直到最后队列变空
if(x >= 0 && x < image.length && y >= 0 && y < image[0].length
&& image[x][y] == oldColor){
image[x][y] = newColor;
queue.add(new int[]{x,y});
}
}
}
return image;
}
}
关于广度优先搜索(BFS)与深度优先搜索(DFS)
广度优先搜索和深度优先搜索都是一种用于遍历或者搜索树和图的算法。
对于树或者图,广度优先搜索的思想是从第一个节点开始,逐层遍历,即一层一层地搜索,遍历父节点的所有子节点,然后重复此过程,直至遍历完所有的节点。
深度优先搜索的思想是先从第一个节点出发,然后沿着一条路径一直走到底,如果发现没有找到目标节点,则返回到上一个节点,然后从另一条路一直走到底,重复这个过程直至找到目标解。在深度优先搜索中有一个回溯的过程。