LeetCodeAnimation/0994-orangesRotting/Article/0994-orangesRotting.md
2020-05-06 11:35:35 +08:00

112 lines
4.5 KiB
Java
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## LeetCode第994号问题腐烂的橘子
> 本文首发于公众号图解面试算法 [图解 LeetCode ](<https://github.com/MisterBooo/LeetCodeAnimation>) 系列文章之一。
>
> 同步个人博客www.zhangxiaoshuai.fun
本题在leetcode中题目序号994属于medium级别目前通过率为50.7%
**题目描述**
```
在给定的网格中每个单元格可以有以下三个值之一
值0代表空单元格
值1代表新鲜橘子
值2代表腐烂的橘子
每分钟任何与腐烂的橘子在4个正方向上相邻的新鲜橘子都会腐烂返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数如果不可能返回-1
示例1
输入[[2,1,1],[1,1,0],[0,1,1]]
输出4
示例2
输入[[2,1,1],[0,1,1],[1,0,1]]
输出-1
解释左下角的橘子第2行第0列永远不会腐烂因为腐烂只会发生在4个正向上
示例3
输入[[0,2]]
输出0
解释因为0分钟时已经没有新鲜橘子了所以答案就是0
提示
1<=grid.length<=10
1<=grid[0].length<=10
grid[i][j]仅为01或2
```
**由题意只有腐烂的橘子才可以去污染它周围四个方向上存在的新鲜橘子且它每一分钟只能污染一次下一次被它腐蚀的橘子再去腐蚀自己周边的新鲜橘子每次只有被新腐蚀的橘子才能继续向外腐蚀因为旧的腐烂的橘子已经被包围**
这就很像一个人得了传染病只要他遇见人就会将病传染给那个人而被传染的又会去感染别的人不同的是这里的橘子的位置是固定的无法移动
思路是非常简单的我们通过动态图直观理解下
![腐烂的橘子gif演示](../Animation/腐烂的橘子01.gif)
既然理清了思路那么我们来试试代码
首先我们需要知道初始状态下的单元格中有多少腐烂的橘子并且要将它们的位置信息保存下来我们可以用一个队列**先入先出**xy保存下来;然后我们开始遍历整个队列每次弹出一个保存的位置信息将这个位置周围的新鲜橘子全部腐蚀并且将被腐蚀的橘子的位置信息存入队列中在下次循环中从它们的位置上再**向外延伸**注意为了模拟同步我们需要将每次存入队列中的所有位置都要在下一次全部取出来直到队列为空循环结束这个时候并不能说明整个单元格中已经不存在新鲜的橘子因为可能存在下面这种情况
![](../Animation/example01.png)
很明显标红的区域新鲜橘子永远不能被腐蚀因为它周围唯一的两个单元格是空的
那么针对这种情况我们在前面遍历统计腐烂橘子的时候可以顺便统计一下新鲜橘子的数量count后面我们每腐蚀一个橘子就从count中减去1最终循环结束的时候我们只需要判断count是否大于0若是返回-1否则返回轮数res
------
**代码**
```java
public static int orangesRotting02(int[][] grid){
int row = grid.length,col = grid[0].length;
Queue<int[]> queue = new ArrayDeque();
int count = 0;//统计新鲜橘子的数量
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (grid[i][j] == 2) {
queue.add(new int[]{i,j});
}
if (grid[i][j] == 1) {
count++;
}
}
}
int res = 0;
while (count > 0 && !queue.isEmpty()) {
res++;
int size = queue.size();
for (int i = 0; i < size; i++) {
int[] temp = queue.poll();
int r = temp[0],c = temp[1];//(x,y)
//上
if (r > 0 && grid[r-1][c] == 1) {
grid[r-1][c] = 2;
count--;
queue.add(new int[]{r-1,c});
}
//下
if (r < grid.length-1 && grid[r+1][c] == 1) {
grid[r+1][c] = 2;
count--;
queue.add(new int[]{r+1,c});
}
//左
if (c > 0 && grid[r][c-1] == 1) {
grid[r][c-1] = 2;
count--;
queue.add(new int[]{r,c-1});
}
//右
if (c < grid[0].length-1 && grid[r][c+1] == 1) {
grid[r][c+1] = 2;
count--;
queue.add(new int[]{r,c+1});
}
}
}
if (count > 0) {
return -1;
}
return res;
}
```