题目
思路
题目是返回直到单元格中没有新鲜橘子为止所经历的最小分钟数。也就是求腐烂橘子到新鲜橘子的最小路径,可以用广度优先搜索算法(BFS)。
有点类似JVM垃圾回收的过程,先初始标记GCROOTS(刚开始的坏橘子),再用根搜索算法往下找(有连接的都会被传染),没有在链路上的就是可回收对象(新鲜橘子)。
1.初始标记。计算好橘子的个数并将坏橘子放入队列
2.根搜索。对坏橘子的坐标进行上下左右搜索
3.判断最终结果
代码
private static int orangeRotting(int[][] grid) {
//先计算好橙子的数量
int good = 0;
Queue<int[]> queue = new LinkedList<>();
int hang = grid.length;
int lie = grid[0].length;
//初始标记
for (int i = 0; i < hang; i++) {
for (int j = 0; j < lie; j++) {
int n = grid[i][j];
if (n == 1) {
good++;
} else if (n == 2) {
//坏橘子放队列中 第0轮就被感染的橘子
queue.add(new int[]{i, j});
}
}
}
int round = 0;
//根搜索算法
//再循环感染
while (good > 0 && !queue.isEmpty()) {
round++;
int size = queue.size();
//第1轮,把橘子循环放出来霍霍人
for (int i = 0; i < size; i++) {
//坏橘子的坐标
int[] bad = queue.poll();
int r = bad[0];
int c = bad[1];
//往上感染 别越界
if (r - 1 >= 0 && grid[r - 1][c] == 1) {
//感染成坏的
grid[r - 1][c] = 2;
//放到坏橘子队列
queue.add(new int[]{r - 1, c});
//好橘子数量-1
good--;
}
//往下感染
if (r + 1 < hang && grid[r + 1][c] == 1) {
grid[r + 1][c] = 2;
queue.add(new int[]{r + 1, c});
good--;
}
//往左感染
if (c - 1 >= 0 && grid[r][c - 1] == 1) {
grid[r][c - 1] = 2;
queue.add(new int[]{r, c - 1});
good--;
}
//往右感染
if (c + 1 < lie && grid[r][c + 1] == 1) {
grid[r][c + 1] = 2;
queue.add(new int[]{r, c + 1});
good--;
}
}
}
//有幸存者
if (good > 0) {
return -1;
} else {
//经过了几轮感染
return round;
}
}