腐烂的橘子
难度:
标签:
题目描述
在给定的 m x n
网格 grid
中,每个单元格可以有以下三个值之一:
- 值
0
代表空单元格; - 值
1
代表新鲜橘子; - 值
2
代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1
。
示例 1:
输入:grid = [[2,1,1],[1,1,0],[0,1,1]] 输出:4
示例 2:
输入:grid = [[2,1,1],[0,1,1],[1,0,1]] 输出:-1 解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个方向上。
示例 3:
输入:grid = [[0,2]] 输出:0 解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 10
grid[i][j]
仅为0
、1
或2
代码结果
运行时间: 18 ms, 内存: 16.1 MB
/*
* 思路:
* 1. 首先统计所有新鲜橘子的数量,并将所有腐烂橘子的坐标放入队列。
* 2. 使用广度优先搜索(BFS)算法,每次从队列中取出一个腐烂的橘子,将它周围的新鲜橘子腐烂。
* 3. 每腐烂一层新鲜橘子,时间加1,直到没有新鲜橘子。
* 4. 最后,检查是否还有新鲜橘子,若有返回-1,否则返回时间。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public int orangesRotting(int[][] grid) {
int rows = grid.length;
int cols = grid[0].length;
int freshOranges = 0;
Queue<int[]> rottenQueue = new LinkedList<>();
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (grid[r][c] == 1) {
freshOranges++;
} else if (grid[r][c] == 2) {
rottenQueue.offer(new int[]{r, c});
}
}
}
if (freshOranges == 0) return 0;
int minutes = 0;
int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
while (!rottenQueue.isEmpty()) {
int size = rottenQueue.size();
List<int[]> newRotten = IntStream.range(0, size).mapToObj(i -> rottenQueue.poll()).flatMap(point -> Arrays.stream(directions).map(dir -> new int[]{point[0] + dir[0], point[1] + dir[1]}).filter(xy -> xy[0] >= 0 && xy[0] < rows && xy[1] >= 0 && xy[1] < cols && grid[xy[0]][xy[1]] == 1).peek(xy -> { grid[xy[0]][xy[1]] = 2; freshOranges--; })).collect(Collectors.toList());
rottenQueue.addAll(newRotten);
if (!rottenQueue.isEmpty()) minutes++;
}
return freshOranges == 0 ? minutes : -1;
}
}
解释
方法:
This solution uses the Breadth-First Search (BFS) algorithm to simulate the rotting process of oranges. It starts by identifying all initially rotten oranges and counting fresh oranges. It enqueues all rotten oranges' positions. Using BFS, it iteratively infects fresh oranges adjacent to rotten ones each minute, marking them rotten and decreasing the fresh count. This continues until no fresh oranges are left or there are no more adjacent fresh oranges to infect, at which point the process stops. If any fresh oranges remain unreachable, it returns -1, otherwise, it returns the number of minutes passed.
时间复杂度:
O(M * N)
空间复杂度:
O(M * N)
代码细节讲解
🦆
在算法中,为何选择使用广度优先搜索(BFS)而不是深度优先搜索(DFS)来模拟橘子腐烂的过程?
▷🦆
请问算法在处理边界条件时,如何确保不会访问到网格之外的位置?
▷🦆
为什么在每一轮中需要使用一个队列来存储即将腐烂的橘子的位置?
▷🦆
在BFS执行过程中,如果某一分钟没有新的橘子腐烂,算法是否会提前终止,还是会继续执行直到遍历完所有橘子?
▷