LeetCode 994 腐烂的橘子

在给定的 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 == gridi.length

1 <= m, n <= 10

gridij 仅为 0、1 或 2

Python代码:

python 复制代码
from typing import List
from collections import deque

class Solution:
    def orangesRotting(self, grid: List[List[int]]) -> int:
        # 网格的行数和列数
        row_count = len(grid)
        col_count = len(grid[0]) if row_count > 0 else 0
        
        # 存储腐烂橘子的位置,用于广度优先搜索
        # BFS队列中的每个元素是坐标 (行, 列)
        rotten_positions = deque()
        
        # 统计新鲜橘子的总数,用于判断是否能全部腐烂
        fresh_oranges = 0
        
        # 第一步:遍历网格,初始化队列和新鲜橘子数量
        for row in range(row_count):
            for col in range(col_count):
                # 发现腐烂橘子,加入队列
                if grid[row][col] == 2:
                    rotten_positions.append( (row, col) )
                # 发现新鲜橘子,计数加1
                elif grid[row][col] == 1:
                    fresh_oranges += 1
        
        # 特殊情况:如果一开始就没有新鲜橘子,直接返回0
        if fresh_oranges == 0:
            return 0
        
        # 定义四个扩散方向:上、下、左、右
        # 每个方向是(行变化量, 列变化量)
        directions = [ (-1, 0), (1, 0), (0, -1), (0, 1) ]
        
        # 记录经过的分钟数
        minutes_passed = 0
        
        # 第二步:BFS扩散,模拟每分钟的腐烂过程
        # 循环条件:队列中还有腐烂橘子,且还有新鲜橘子
        while rotten_positions and fresh_oranges > 0:
            # 当前分钟需要处理的腐烂橘子数量(当前层级的节点数)
            current_rotten_count = len(rotten_positions)
            
            # 处理当前分钟的所有腐烂橘子(确保同一分钟的腐烂同时发生)
            for _ in range(current_rotten_count):
                # 取出一个腐烂橘子的位置
                current_row, current_col = rotten_positions.popleft()
                
                # 检查四个方向的相邻单元格
                for dr, dc in directions:
                    # 计算相邻单元格的坐标
                    new_row = current_row + dr
                    new_col = current_col + dc
                    
                    # 检查相邻单元格是否在网格范围内
                    is_in_grid = (0 <= new_row < row_count) and (0 <= new_col < col_count)
                    
                    # 如果在网格内,且是新鲜橘子
                    if is_in_grid and grid[new_row][new_col] == 1:
                        # 标记为腐烂橘子
                        grid[new_row][new_col] = 2
                        # 新鲜橘子数量减少
                        fresh_oranges -= 1
                        # 将新腐烂的橘子加入队列,用于下一分钟的扩散
                        rotten_positions.append( (new_row, new_col) )
            
            # 处理完当前分钟的所有腐烂橘子,时间加1
            minutes_passed += 1
        
        # 第三步:判断结果
        # 如果所有新鲜橘子都腐烂了,返回所用时间
        # 否则,返回-1(存在无法腐烂的橘子)
        return minutes_passed if fresh_oranges == 0 else -1
相关推荐
aqiu11111116 分钟前
【算法日记 13】LeetCode 49. 字母异位词分组:哈希表的进阶“降维打击”
算法·leetcode·散列表
KaMeidebaby25 分钟前
卡梅德生物技术快报|纳米抗体技术全套实操流程:AFB1 全合成文库淘选 + 分子对接定点突变参数手册
人工智能·python·tcp/ip·算法·机器学习
帅次32 分钟前
Android 高级工程师面试:Flow 与状态流 近1年高频追问 22 题
android·面试·职场和发展
巴糖1 小时前
从做早餐理解 DAG 与拓扑排序:任务依赖图的核心逻辑
算法
2601_962851741 小时前
计算机毕业设计之基于YOLOV10的低光照目标检测算法研究与实现
大数据·算法·yolo·目标检测·信息可视化·cnn·课程设计
magicwt1 小时前
快手自动出价论文GAVE阅读笔记
算法
智者知已应修善业1 小时前
【P12159蓝桥杯数组翻转】2025-4-24
c语言·c++·经验分享·笔记·算法·蓝桥杯
小巧的砖头2 小时前
使用SVN+CruiseControl+ANT实现持续集成之一
学习·算法
人道领域2 小时前
【LeetCode刷题日记】贪心算法理论与实战:455.分发饼干最优解
java·开发语言·数据结构·算法·leetcode·贪心算法
小O的算法实验室3 小时前
2026年ACM TCH,动态救护车路径优化:结合 K-means 聚类与多目标粒子群算法两阶段策略
算法