文章目录
1.算法简介
这个算法是关于我们的floodfill的相关的问题,这个算法其实从名字就可以看出来:洪水灌溉,其实这个算法的过程就和他的名字非常相似,下面的这个图就生动的展示了这个算法的相关原理;
其实这个就是想要找到性质相同的联通快:使用下面的这个图形里面的数据作为例子,第二行第二列的这个数据是5,当洪水从左上角进来的时候,你可以把这个区域想象成为一个梯田,当洪水来临的时候,左上角的这个-1,-2,-3都会被淹掉,我们可以把这个想象成为地理上面学习的这个等高线之类的,地势低的位置肯定是先被淹掉,这个应该是很容易理解的;
同理,当这个洪水从右上方来临的时候,负数的更小,对应的这个区域肯定会被淹没,这个是显然的;
大致就是这个过程,为什么这个和我们的bfs相关呢?因为我们确定这个被淹没的区域的时候,思路就是从他身边的进行比较,如果高的话,自己肯定机会呗淹没了,但是如果对方低的话,对方就会被淹掉,通过不断的这个遍历搜索的过程,最终确定想要的结果;
这个思路比较简单,但是过程很抽象,我们通过leetcode上面的一个具体的题目进行说明;

2.题目概述
下面的这个就是关于洪水灌溉的题目:leetcode773图像渲染;

解释一下上面的这个示例想要表达的意思把:我觉得相对于上面的大段的文字,这个示例图示会更加容易理解一些,这个示例的意思就是给你一个sr,sc,color,这个sr和sc表示的就是需要被渲染的搜索起点,我们从这个位置开始,这个color就是把这个相关的符合条件的点全部染成这个color对应的颜色;
看这个(1,1)表示的就是第二行的第二列对应的元素,这个很好理解,这个元素就是1,而我们需要渲染的这个颜色就是2,两个是不一样的,因此这个需要我们进行操作,如果两个的颜色是一样的,这个过程就是多余的,因此我们写代码的时候需要进行判断一下;
周围的这个点必须是直接相邻的,可以是sr,sc的邻居,也可以是他的邻居的邻居,大家可以理解我的意思吧,总之这个区域需要是联通的,不可以是分散的孤立的,这个是重点;
3.算法原理
理解上面的这个题目对应的示例之后,接下来开始进行这个算法的原理的分析:
下面的这个是一个新的图,进行这个算法的原理的说明,sr,sc还是(1,1),color=2,说明以这个(1,1)作为起点,这个color就是我们想要把这个相关的点染成的颜色为2;
下面的这个是第一步,现对于这个(1,1)上下左右的位置进行判断:发现了两个目标,就是图里面的斜线经过的两个点的位置;

下面的是新的一轮的搜索,这个时候是以上面的两个作为基础,继续操作,这个时候又找到了三个符合条件的数据点的坐标

下面的这个是:在上一步的基础上面继续操作,这个时候找到了两个符合条件的坐标;

接下来轮到第四层的时候,发现第三层的这个元素的周围已经没有其他的元素的,因此这个时候我们的这个广度优先遍历的过程就结束了;
4.代码分析
- 刚开始的这个dx,dy数组是后面进行上下左右的遍历的时候用到的,下面的这个图片会进行说明;
- prev就是题目给定的这个位置的元素值,我们需要判断他和color是不是一样的,如果是有一样的,接下来就不需要进行判断了;
- m,n的定义主要是为了越界问题的定义,我们首先把这个sr,sc放到这个队列里面去;
- 循环里面,我们取出来这个对首的元素,因为这个队列里面的每一个元素都是一个二维的数组,我们使用这个a,b记录他对应的横纵坐标即可,然后进行对应的颜色的渲染;
- 里面的这个for循环就是上下左右进行判断的,符合条件的进行染色,最后返回处理之后的image即可;
java
class Solution {
int[] dx={0,0,1,-1};
int[] dy={1,-1,0,0};
public int[][] floodFill(int[][] image, int sr, int sc, int color) {
int prev=image[sr][sc];
if(prev==color) return image;
int m=image.length,n=image[0].length;
Queue<int[]> q=new LinkedList<>();
q.add(new int[]{sr,sc});
while(!q.isEmpty()){
int[] t=q.poll();
int a=t[0],b=t[1];
image[a][b]=color;
for(int i=0;i<4;i++){
int x=a+dx[i],y=b+dy[i];
if(x>=0&&x<m&&y>=0&&y<n&&image[x][y]==prev){
q.add(new int[]{x,y});
}
}
}
return image;
}
}
下面的这个图是说明我们的上下左右的坐标是如何表示的:
上下左右,发现这个点的坐标就是-1,+1的操作,因此我们定义了这个dx,dy数组,在上面的这个代码的for循环里面,我们使用这个数组相当于是完成了对于这个已知点的周围的几个点的判断,这个很方便,大家可以借鉴一下;
操作,因此我们定义了这个dx,dy数组,在上面的这个代码的for循环里面,我们使用这个数组相当于是完成了对于这个已知点的周围的几个点的判断,这个很方便,大家可以借鉴一下;
