多源bfs,LeetCode 994. 腐烂的橘子

一、题目

1、题目描述

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

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

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

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

2、接口描述

python3
复制代码
python 复制代码
class Solution:
    def orangesRotting(self, grid: List[List[int]]) -> int:
cpp
复制代码
cpp 复制代码
class Solution {
public:
    int orangesRotting(vector<vector<int>>& grid) {

    }
};

3、原题链接

994. 腐烂的橘子


二、解题报告

1、思路分析

初始遍历网格将所有腐烂橘子入队,同记录当前所有的新鲜橘子个数

如果队列不空并且有新鲜橘子,我们就将当前队列的坐标全部出队扩展一层,只能扩展那些新鲜橘子的格子,并将其改为不新鲜

最终返回时如果仍有新鲜橘子就返回-1,否则返回bfs扩展的层数即时间

2、复杂度

时间复杂度: O(NM) 空间复杂度:O(NM)

3、代码详解

python3
复制代码
python 复制代码
class Solution:
    def orangesRotting(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        q = []
        tot = 0
        for i, row in enumerate(grid):
            for j, x in enumerate(row):
                if x == 1:
                    tot += 1
                elif x == 2:
                    q.append((i, j))
        ret = 0
        while q and tot:
            ret += 1
            nq = []
            for x, y in q:
                for nx, ny in (x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1):
                    if nx < 0 or ny < 0 or nx >= m or ny >= n or grid[nx][ny] != 1:
                        continue
                    grid[nx][ny] = 2
                    tot -= 1
                    nq.append((nx, ny))
                q = nq

        return ret if tot == 0 else -1
cpp
复制代码
cpp 复制代码
class Solution {
public:
typedef pair<int, int> PII;
static constexpr int dst[5] { 1, 0, -1, 0, 1 };
    int orangesRotting(vector<vector<int>>& grid) {
        queue<PII> q;
        int m = grid.size(), n = grid[0].size();
        int ret = 0, tot = 0;
        for(int i = 0; i < m; i ++)
            for(int j = 0; j < n; j ++)
                if (grid[i][j] == 2) q.emplace(i, j);
                else if(grid[i][j] == 1) tot ++;
        while (q.size() && tot) {
            ret ++;
            for(int i = 0, ed = q.size(); i < ed; i ++) {
                auto [x, y] = q.front();
                q.pop();
                for (int j = 0; j < 4; j ++) {
                    int nx = x + dst[j], ny = y + dst[j + 1];
                    if (nx < 0 || ny < 0 || nx >= m || ny >= n) continue;
                    if (grid[nx][ny] != 1) continue;
                    tot -= grid[nx][ny];
                    grid[nx][ny] = 2;
                    q.emplace(nx, ny);
                }
            }
        }
        return tot ? -1 : ret;
    }
};
相关推荐
青い月の魔女2 分钟前
数据结构初阶---二叉树
c语言·数据结构·笔记·学习·算法
林的快手1 小时前
209.长度最小的子数组
java·数据结构·数据库·python·算法·leetcode
千天夜1 小时前
多源多点路径规划:基于启发式动态生成树算法的实现
算法·机器学习·动态规划
从以前1 小时前
准备考试:解决大学入学考试问题
数据结构·python·算法
.Vcoistnt1 小时前
Codeforces Round 994 (Div. 2)(A-D)
数据结构·c++·算法·贪心算法·动态规划
ALISHENGYA2 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(实战训练三)
数据结构·c++·算法·图论
Dream it possible!4 小时前
LeetCode 热题 100_LRU 缓存(35_146_中等_C++)(哈希表 + 双向链表)(构造函数声明+初始化列表=进行变量初始化和赋值)
c++·leetcode·缓存
我码玄黄4 小时前
正则表达式优化之算法和效率优化
前端·javascript·算法·正则表达式
Solitudefire5 小时前
蓝桥杯刷题——day9
算法·蓝桥杯
三万棵雪松5 小时前
1.系统学习-线性回归
算法·机器学习·回归·线性回归·监督学习