同样的规矩,我们从题目入手:
有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。
给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor,让你重新上色这幅图像。
为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。
最后返回经过上色渲染后的图像。
示例:
输入:
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,
因为它不是在上下左右四个方向上与初始点相连的像素点。
题目本身很简单,但是题目读完可能一脸蒙蔽,这是一道很经典的广度优先遍历/深度优先遍历的问题。我用很通俗的语言给大家解释一下 这道题目的大致含义:
题目的核心就是给定一个矩阵,我们从一个点出发,然后找出该点所有的相临结点,同时一旦发现该相邻结点的颜色和初始结点相同我们就将其值改为指定值
题目示例中给出的矩阵如下所示:
给出的初始坐标为(1,1),即从(1,1)号位置出发,对应如下图所示的点出发
然后依次访问该点的相邻(上下左右)的结点,(0,1):1和(1,1)对应的值相同,入队,(2,0):0,和(1,1)对应的值不相同,不入队,(1,0):1满足入队,(1,2):0不满足,最终队列的情况为:[ (0,1),(1,0) ]
接下来让(0,1)出队,同时让(0,1)的相邻结点依次入队,(0,0):1满足,入队,(0,2):1满足,入队。最终队列的情况为:[ (1,0),(0,0),(0,2)],注意:每个入队的的结点值需要更换成newColor的值
以上操作其本质就是广度优先遍历。
代码如下:
package com.exercise.leetecode.深度and广度搜索;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
/**
* 题目:图像渲染
* 题目编号:733
* 题目链接:https://leetcode-cn.com/problems/flood-fill/
*/
public class 图像渲染_733 {
public static int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
//定义上下左右移动的顺序列表
int[] dx = {0, 0, 1, -1};
int[] dy = {1, -1, 0, 0};
if (image[sr][sc] == newColor)//如果发现值已经和给定值一样,无需再继续搜索
return image;
int oldColor = image[sr][sc];//保存原来的结点值
image[sr][sc] = newColor;//将起始结点
Queue<int[]> queue = new LinkedList<int[]>();//声明队列,用于存储遍历的结点坐标
queue.add(new int[]{sr, sc});
int r_l = image.length;//行的边界值
int c_l = image[0].length;//列的边界值
while (!queue.isEmpty()) {
//出队
int[] t = queue.poll();
int x = t[0], y = t[1];
for (int i = 0; i < 4; i++) {
int mx = x + dx[i];
int my = y + dy[i];
if (mx >= 0 && my >= 0 && mx < r_l && my < c_l && image[mx][my] == oldColor) {
image[mx][my] = newColor;
queue.offer(new int[]{mx, my});
}
}
}
return image;
}
public static void print(int[][] image) {
for (int i = 0; i < image.length; i++) {
for (int j = 0; j < image[0].length; j++) {
System.out.print(image[i][j] + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
int[][] image = {{1, 1, 1}, {1, 1, 0}, {1, 0, 1}};
int sr = 1, sc = 1, newColor = 2;
print(floodFill(image, sr, sc, newColor));
}
}
至此讲解就结束了