在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:
值 0 代表空单元格; 值 1 代表新鲜橘子; 值 2 代表腐烂的橘子。 每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。

此题是一个多源 BFS 问题。关键在于把几个循环嵌套的逻辑想清楚,同时能想到维护一个 fresh 变量作为新鲜橘子的个数,从而作为最终是否能够全部腐烂的判断依据。
C++54 linesExpandCollapse
int orangesRotting(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
int fresh = 0;
int minutes = 0;
queue<pair <int, int>> q;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) fresh++;
if (grid[i][j] == 2) q.push({i, j});
}
}
if (fresh == 0) return 0;
// 枚举 4 个方向
int directions[4][2] = {
{1, 0},
{0, 1},
{-1, 0},
{0, -1}
};
// 每轮循环代表一次 BFS,即 1 分钟
while (!q.empty() && fresh > 0) {
minutes++;
int size = q.size();
// 每轮循环对应一个当前队列中腐烂的橘子
while (size--) {
// 从队列中取出腐烂橘子的坐标
auto [x, y] = q.front();
q.pop();
// 遍历 4 个方向的相邻位置
for (auto& [dx, dy] : directions) {
int newX = x + dx;
int newY = y + dy;
if (newX < 0 || newY < 0 || newX >= m || newY >= n || grid[newX][newY] != 1) {
continue;
}
grid[newX][newY] = 2;
fresh--;
q.push({newX, newY});
}
}
}
return fresh == 0 ? minutes : -1;
}