From 063655d7aeb99335f7fa7c7c1e92faa3ce809183 Mon Sep 17 00:00:00 2001 From: Juan Date: Sun, 17 Jul 2022 15:22:55 +0800 Subject: [PATCH] vault backup: 2022-07-17 15:22:55 --- OJ notes/pages/Leetcode Rotting-Oranges.md | 172 +++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 OJ notes/pages/Leetcode Rotting-Oranges.md diff --git a/OJ notes/pages/Leetcode Rotting-Oranges.md b/OJ notes/pages/Leetcode Rotting-Oranges.md new file mode 100644 index 0000000..27601df --- /dev/null +++ b/OJ notes/pages/Leetcode Rotting-Oranges.md @@ -0,0 +1,172 @@ +# Leetcode Rotting-Oranges + +#### 2022-07-17 15:12 + +> ##### Algorithms: +> #algorithm #BFS +> ##### Data structures: +> #DS #vector_2d +> ##### Difficulty: +> #coding_problem #difficulty-medium +> ##### Additional tags: +> #leetcode +> ##### Revisions: +> N/A + +##### Related topics: +```expander +tag:# +``` + + + +##### Links: +- [Link to problem](https://leetcode.com/problems/rotting-oranges/) +___ +### Problem + +You are given an `m x n` `grid` where each cell can have one of three values: + +- `0` representing an empty cell, +- `1` representing a fresh orange, or +- `2` representing a rotten orange. + +Every minute, any fresh orange that is **4-directionally adjacent** to a rotten orange becomes rotten. + +Return _the minimum number of minutes that must elapse until no cell has a fresh orange_. If _this is impossible, return_ `-1`. + +#### Examples + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2019/02/16/oranges.png) + +``` +**Input:** grid = [[2,1,1],[1,1,0],[0,1,1]] +**Output:** 4 +``` + +**Example 2:** + +``` +**Input:** grid = [[2,1,1],[0,1,1],[1,0,1]] +**Output:** -1 +``` +**Explanation:** The orange in the bottom left corner (row 2, column 0) is never rotten, because rotting only happens 4-directionally. + +**Example 3:** + +``` +**Input:** grid = [[0,2]] +**Output:** 0 +``` +**Explanation:** Since there are already no fresh oranges at minute 0, the answer is just 0. + +#### Constraints + +- `m == grid.length` +- `n == grid[i].length` +- `1 <= m, n <= 10` +- `grid[i][j]` is `0`, `1`, or `2`. + +### Thoughts + +> [!summary] +> This is a #BFS problem, because we use it to calculate +> the shortest {time, distance} + +Be wary of these special cases: +- everything is empty cell -> return -1, no orange => no + fresh orange +- everything is rotten -> return 0 +- everything is fresh -> return -1, impossible to rot + +> [!tip] update the value in place vs. in queue +> Update in place, such as +> ```cpp +> if (grid[a + 1][b] != 0) { +> queue.push({a, b}); +> grid[a + 1][b] = 0; +> } +> ``` +> Can avoid multiple enqueues, because the value is already +> updated, so another node in queue can't push that again. +> ```cpp +> grid[a][b] = 0; +> if (grid[a + 1][b] != 0) { +> queue.push({a, b}); +> } +> ``` +> this code might result in pushing the same node twice. + +### Solution + +```cpp +class Solution { +public: + int orangesRotting(vector> &grid) { + // BFS + queue> todo; + int m = grid.size(), n = grid[0].size(); + int time = -1; + bool isGridEmpty = true; + int freshCount = 0; + + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 2) { + // add to queue, rotten + todo.push({i, j}); + } else if (grid[i][j] == 1) { + freshCount++; + } + if (isGridEmpty && grid[i][j] != 0) { + isGridEmpty = false; + } + } + } + + int x, y; + int offset[] = {-1, 1}; + int newX, newY; + + // if there is no value, there's no orange -> no fresh orange + if (isGridEmpty) { + return 0; + } + + while (!todo.empty()) { + for (int i = 0, size = todo.size(); i < size; i++) { + x = todo.front().first; + y = todo.front().second; + todo.pop(); + + for (int o : offset) { + newX = x + o; + if (newX >= 0 && newX < m && grid[newX][y] == 1) { + todo.push({newX, y}); + // cout<<"Pushed: "<= 0 && newY < n && grid[x][newY] == 1) { + todo.push({x, newY}); + // cout<<"Pushed: "<