题目
有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。
给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor,让你重新上色这幅图像。
为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。
最后返回经过上色渲染后的图像。
题目传送门
思路
真的很巧合,最近刚刚好在学深搜和广搜。今天看到这道题,我居然会想到用广搜去做,我还以为是我最近想得太多,结果就直接这样想了,没想到最后一想,还是真的得需要用广搜去做!
这道题有点像那种问你一片地方里面多少个小岛的题目,就是要搜当前的有多少个数值跟你指定的数值是相等的并且连在一起,找出来并改变它。
因为我们要找出sr,sc位置,并且,在他的上下左右四个位置,只要数值跟它相同的,就要继续染色,循环这个过程,知道染色完成。。
我们首先新建一个点类,然后把当前的sr,sc当做头结点入队,然后,开始进行广度搜索。搜这个点的上下左右四个方向,只要它的数值跟当前的数值一样,该节点就是可以染色的,我们就把这个节点给加入到队伍中来。
然后,我们先取出队首的横纵坐标,并且搜索他的上下左右四个方向,然后,把符合条件的点加入队列,把当前点染色,标记为已经搜索了,并且弹出队首。循环和这个过程,直到队列为空。。
代码
import java.util.LinkedList;
import java.util.Queue;
class point{
int x;
int y;
}
class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
int color = image[sr][sc];
if (color == newColor) {
return image;
}
Queue <point> queue=new <point> LinkedList();
point t=new point();
t.x=sr;
t.y=sc;
queue.offer(t);
//方向数组,左上右下
int d_x[]={0,-1,0,1};
int d_y[]={-1,0,1,0};
int a=0;//临时变量
int b=0;//临时变量
int temp_a=0;
int temp_b=0;
int visited[][]=new int[image.length][image[0].length];
while (!queue.isEmpty())//队列不为空
{
a=queue.peek().x;
b=queue.peek().y;
for (int i=0;i<=3;++i)//搜索上下左右四个点,把可扩展的加到队列里面
{
temp_a=a+d_x[i];
temp_b=b+d_y[i];
if (temp_a>=0 && temp_a<image.length && temp_b>=0 && temp_b<image[0].length && image[a][b]==image[temp_a][temp_b] && visited[temp_a][temp_b]==0)
{
point d=new point();
d.x=temp_a;
d.y=temp_b;
visited[temp_a][temp_b]=1;
queue.offer(d);
}
}
image[a][b]=newColor;//染色
queue.poll();//剔除已经染色的点
}
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();
}
return image;
}
}
结果
虽然ac了,可是这道题卡得太久了,昨天刚刚学了广搜,所以不是很熟悉,不过按照模板来,倒是不是很难,主要一个点,我偷懒了,我以为这个染色之后,数值改变了,就没有使用标记数组,结果,死循环了一个下午。。浪费了4个小时的时间。。。以后要改,改有的东西,搜索都还是要配备上的。
不过也很有收获,这个是昨天看了别人视频后,自己写出来的第二道广搜题目。终于征服了以前那个不敢去尝试搜索算法的心魔。。冲冲冲,算法之路无穷尽也!!!