【算法】 腐烂的橘子

113 阅读1分钟

难度:中等

题目

在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:

  • 0 代表空单元格;
  • 1 代表新鲜橘子;
  • 2 代表腐烂的橘子。

每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。

返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回-1。

示例:

示例1:

输入:grid = [[2,1,1],[1,1,0],[0,1,1]]

输出:4

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 10
  • grid[i][j] 仅为 012

解题思路:

腐烂的橘子问题(Rotting Oranges)涉及到在一个给定的网格中,某些单元格包含新鲜橘子(值为 1),某些单元格包含腐烂的橘子(值为 2),还有些单元格为空(值为 0)。腐烂的橘子会传染给相邻(上下左右)的新鲜橘子,使得它们在一分钟后也腐烂。任务是计算直到所有新鲜橘子都腐烂所需的分钟数,如果不可能则返回 -1。

  1. 初始化:创建一个队列 queue,用于存储腐烂橘子的位置。同时,计算总共有多少新鲜橘子。
  2. 广度优先搜索(BFS):从所有初始的腐烂橘子开始,使用 BFS 遍历网格。将所有初始的腐烂橘子位置加入队列,并开始 BFS 过程。
  3. 传播腐烂:在每一轮 BFS 中,从队列中取出腐烂橘子的位置,检查其四个相邻的单元格。如果相邻单元格中有新鲜橘子(值为 1),则将其标记为腐烂(值改为 2),并加入队列中等待下一轮传染。
  4. 更新时间:每完成一轮 BFS,表示所有能够被感染的新鲜橘子都已经变为腐烂状态,这时将时间加一。
  5. 检查是否全部腐烂:在 BFS 结束后,检查是否有新鲜橘子仍然存在。如果有,说明有些橘子永远无法腐烂,返回 -1。如果没有,返回经过的时间。

JavaScript实现:

function orangesRotting(grid) {
    const m = grid.length;
    const n = grid[0].length;
    let freshOranges = 0;
    const queue = [];
    const directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];

    // 初始化
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (grid[i][j] === 2) {
                queue.push([i, j]);
            } else if (grid[i][j] === 1) {
                freshOranges++;
            }
        }
    }

    let minutes = 0;

    while (queue.length > 0 && freshOranges > 0) {
        const size = queue.length;
        for (let i = 0; i < size; i++) {
            const [r, c] = queue.shift();
            for (const [dr, dc] of directions) {
                const nr = r + dr;
                const nc = c + dc;
                if (nr >= 0 && nr < m && nc >= 0 && nc < n && grid[nr][nc] === 1) {
                    grid[nr][nc] = 2; // 橘子腐烂
                    freshOranges--; // 新鲜橘子数量减少
                    queue.push([nr, nc]); // 加入队列
                }
            }
        }
        minutes++; // 时间增加
    }

    return freshOranges === 0 ? minutes : -1;
}
  • 时间复杂度:O(M*N),其中 M 和 N 分别是网格的行数和列数。每个单元格至多被访问两次,一次是在初始化时,另一次是在 BFS 过程中。
  • 空间复杂度:O(M*N),在最坏的情况下,队列可能包含所有单元格