(一)题目描述
有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。
给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor,让你重新上色这幅图像。
为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。
最后返回经过上色渲染后的图像。
(二)解题思路
利用广度优先搜索进行遍历,核心代码如下:
/**
* 广度优先搜索
* @param Vs 起点
* @param Vd 终点
*/
bool BFS(Node &Vs, Node &Vd){
queue<Node> Q;
Node Vn, Vw;
int i;
//初始状态将起点放进队列Q
Q.push(Vs);
hash(Vw) = true;//设置节点已经访问过了!
while (!Q.empty()){//队列不为空,继续搜索!
//取出队列的头Vn
Vn = Q.front();
//从队列中移除
Q.pop();
while(Vw = Vn通过某规则能够到达的节点){
if (Vw == Vd){//找到终点了!
//把路径记录,这里没给出解法
return true;//返回
}
if (isValid(Vw) && !visit[Vw]){
//Vw是一个合法的节点并且为白色节点
Q.push(Vw);//加入队列Q
hash(Vw) = true;//设置节点颜色
}
}
}
return false;//无解
}
核心思想:初始元素入队,队头元素出队,并对根据题中所给要求对出队元素做相应处理,然后依次遍历出队元素的各个方向,并将各个方向的元素入队, 这样不断进行出队入队操作,直至队列为空。(参考:【算法入门】广度/宽度优先搜索(BFS)_raphealguo-CSDN博客_宽度优先搜索)
(三)该题解题代码如下:
class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
//(1)声明一个队列
//(1)声明一个队列,队列中元素为int型数组,其中内容为某元素的横纵坐标
Queue<int[]> queue = new LinkedList<int[]>();
int rowLen=image.length,colLen=image[0].length;
// visit数组标记以访问过的数组元素
boolean[][] visit=new boolean[rowLen][colLen];
int standard=image[sr][sc];
//初始元素先入队
queue.offer(new int[]{sr,sc});
visit[sr][sc]=true;
image[sr][sc]=newColor;
//声明四个方向
int[][] dir={{-1,0},{1,0},{0,1},{0,-1}};
while (!queue.isEmpty()){
//队头元素出队
int[] result=queue.poll();
// 遍历队头元素的四个方向
for (int[] arr:dir){
int rowIndex=result[0]+arr[0];
int colIndex=result[1]+arr[1];
if(rowIndex>=0&&colIndex>=0&&rowIndex<rowLen&&colIndex<colLen){
if(!(visit[rowIndex][colIndex])&&image[rowIndex][colIndex]==standard){
//入队并标记,同时做题中要求的相应操作
queue.offer(new int[]{rowIndex,colIndex});
visit[rowIndex][colIndex]=true;
image[rowIndex][colIndex]=newColor;
}
}
}
}
return image;
}
}