描述
在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。
分析
广度搜索优先的解题思路。
- 为了寻找最短的扩展次数,需要让烂橘子同时向外扩展。
遍历数组找到烂橘子加入道队列当中。 - 每次把队列里面的结点处理完毕,仍然有结点加入道队列当中,就意味着向外扩展了一次。
- 每次便利结束之后要把新鲜的橘子变的与原来不一样,防止重复遍历这个结点。
- 再次遍历数组,如发现仍然存在新鲜的橘子,说明不可能所有的橘子都变烂。
class Solution {
int ans = 0;
public int orangesRotting(int[][] grid) {
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 2) {
queue.offer(new int[]{i,j});
}
}
}
bfs(grid,queue);
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
return -1;
}
}
}
return ans;
}
public void bfs(int[][] grid, Queue<int[]> queue) {
int[][] plus = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
int layer = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int k = 0; k < size; k++) {
int[] pos = queue.poll();
for (int m = 0; m < 4; m++) {
int newi = pos[0] + plus[m][0];
int newj = pos[1] + plus[m][1];
if (newi < 0 || newi >= grid.length || newj < 0 || newj >= grid[0].length || grid[newi][newj] != 1) {
continue;
}
grid[newi][newj] = 2;
queue.offer(new int[]{newi,newj});
}
}
if (!queue.isEmpty()) {
layer++;
}
}
ans = Math.max(layer,ans);
}
}