玩命加载中 . . .

腐烂的橘子


描述

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

值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。

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

示例 1:

img

输入: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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/rotting-oranges
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

该题的主要思路是使用BFS(广度优先搜索)算法,将腐烂橘子的坐标加入队列中,然后遍历队列中的每个腐烂橘子,将其四周的新鲜橘子加入队列中,并将其标记为腐烂状态。每次遍历完当前时间点需要传染的所有橘子后,时间加1。直到队列为空,或者新鲜橘子的数量为0。

如果最终新鲜橘子的数量为0,则返回传染完成的时间;否则返回-1,表示有新鲜橘子没有被传染。

该算法的时间复杂度为O(nm),其中n和m分别为网格的行数和列数,空间复杂度为O(nm),即为队列的大小。

C++代码

class Solution {
public:
    int orangesRotting(vector<vector<int>>& grid) {
        // 定义四个方向,分别为“左, 上, 右, 下”
        int dx[4] = {-1, 0, 1, 0};
        int dy[4] = {0, 1, 0, -1};
        // 定义队列,存储腐烂橘子的坐标
        queue<pair<int, int>> q;
        // 统计新鲜橘子的数量
        int fresh = 0;
        // 获取网格的行数和列数
        int n = grid.size(), m = grid[0].size();
        // 遍历网格,将腐烂橘子的坐标加入队列中,并统计新鲜橘子的数量
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                if(grid[i][j] == 2) {
                    q.push({i, j});
                }
                else if(grid[i][j] == 1) {
                    fresh++;
                }
            }
        }
        // 定义时间变量,记录腐烂的时间
        int time = 0;
        // 如果队列不为空,说明还有腐烂橘子没有传染完
        while(!q.empty() && fresh>0) {
            // 获取当前队列的长度,即为当前时间点需要传染的橘子个数
            int size = q.size();
            // 遍历当前时间点需要传染的所有橘子
            for(int i = 0; i < size; i++) {
                // 获取当前橘子的坐标
                int x = q.front().first, y = q.front().second;
                q.pop();
                // 遍历当前橘子的四个方向
                for(int j = 0; j < 4; j++) {
                    int nx = x + dx[j], ny = y + dy[j];
                    // 如果新的坐标越界或者对应的橘子已经腐烂或者为空,则跳过
                    if(nx < 0 || nx >= n || ny < 0 || ny >= m || grid[nx][ny] != 1) {
                        continue;
                    }
                    // 将新的橘子加入队列中,并将其标记为腐烂状态
                    q.push({nx, ny});
                    grid[nx][ny] = 2;
                    // 每传染一个新鲜橘子,将新鲜橘子的数量减1
                    fresh--;
                }
            }
            // 时间加1
            time++
        }
        return fresh > 0 ? -1 : time;
    }
};

文章作者: Jack Tim
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Jack Tim !
评论
  目录