leetcode刷题记录43-994. 腐烂的橘子

问题描述

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

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

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

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

示例

示例 1:

leetcode刷题记录43-994. 腐烂的橘子_第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 == grid[i].length
  • 1 <= m, n <= 10
  • grid[i][j] 仅为 01 或 2

问题分析:

我想到的就是模拟,这个腐烂的橘子,一次只会影响周边最多四个新鲜的橘子,只要模拟这个过程,以一分钟为循环周期,直到没有发生变化为止(变化是指一轮里没有橘子变烂),统计这个分钟数即可。

ps:一开始写直接没想到队列来存,直接for循环遍历,每次都是1轮全部污染掉,没考虑到本轮腐烂的和之前腐烂的应该是独立的两轮,所以一直错。。。大家一定要注意

代码如下:

class Solution {
public:
    int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
    int orangesRotting(vector>& grid) {
        int n = grid.size(), m = grid[0].size();
        int count = 0;
        deque> orange;
        //    把烂橘子都扔队列里,作为第一轮的开始
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (grid[i][j] == 2)
                    orange.push_back({i, j});
            }
        }
        //    check是否还有新鲜橘子
        auto check = [&]() {
            for (int k = 0; k < n; ++k) {
                for (int q = 0; q < m; ++q) {
                    if (grid[k][q] == 1)
                        return false;
                }
            }
            return true;
        };
        //    周期性污染新鲜橘子
        while (!orange.empty()) {
            int flag = 0;
            int sz = orange.size();
            while (sz--) {
                auto [p, q] = orange.front();
                orange.pop_front();
                bfs(grid, p, q, flag, orange);
            }
            if (flag)
                ++count;
        }
        return check() ? count : -1;
    }
    //    模拟一个腐烂橘子污染新鲜橘子
    void bfs(vector>& grid, int x, int y, int& flag,
             deque>& orange) {
        for (int i = 0; i < 4; ++i) {
            int tx = x + dir[i][0];
            int ty = y + dir[i][1];
            if (tx < 0 || ty < 0 || tx >= grid.size() || ty >= grid[0].size() ||
                grid[tx][ty] != 1) {
                continue;
            }
            grid[tx][ty] = 2;
            flag = 1;
            orange.push_back({tx, ty});
        }
    }
};

你可能感兴趣的:(力扣刷题日记,leetcode,算法,模拟)