-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ba2ea38
commit 8e295ac
Showing
4 changed files
with
154 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Rotting Oranges | ||
|
||
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. | ||
|
||
Example 1 | ||
|
||
![Rotting Oranges](./rotting_oranges.png) | ||
|
||
```plain | ||
Input: grid = [[2,1,1],[1,1,0],[0,1,1]] | ||
Output: 4 | ||
``` | ||
|
||
Example 2: | ||
|
||
```plain | ||
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: | ||
|
||
```plain | ||
Input: grid = [[0,2]] | ||
Output: 0 | ||
``` | ||
|
||
Explanation: Since there are no fresh oranges at minute 0, the answer is just 0. | ||
|
||
## Related Topics | ||
|
||
- Graph | ||
- Matrix | ||
- Array | ||
- Breadth-First Search |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
from typing import List, Deque, Tuple | ||
from collections import deque | ||
|
||
|
||
def oranges_rotting(grid: List[List[int]]) -> int: | ||
"""Returns the minimum time it will take to make all oranges rotten in a grid. If this is not possible, -1 is returned | ||
Since we must track time, a breadth-first search approach makes the most sense, as we can track each iteration of | ||
our bfs loop, and update the time before moving on to the next. | ||
First, we need to iterate our grid looking for rotten oranges to add to our queue. Note, if we also take the time | ||
during this iteration to count the number of fresh oranges, we can save a little time in the end. | ||
Once we have a queue of oranges, we just need to run our BFS and update our time after we exhaust all current cells | ||
in each iteration of it, and finally return the time as long as we have successfully converted all fresh oranges to | ||
rotten ones. | ||
Time Complexity: O(m*n) | ||
where m is the number of rows, and n is the number of columns. We must traverse the graph once to find all our | ||
fresh/rotten oranges, and then potentially again during our BFS. | ||
Space Complexity: O(m*n). In the worst case, all oranges will be rotten, and our queue will be of size m*n. | ||
Args: | ||
grid (List): Grid of oranges. | ||
Returns: | ||
int: minimum number of minutes it will take to make all oranges rotten or -1 if not possible | ||
""" | ||
rows, cols = len(grid), len(grid[0]) | ||
# keep track of rotten oranges | ||
queue: Deque[Tuple[int, int]] = deque([]) | ||
|
||
# number of fresh oranges | ||
fresh = 0 | ||
|
||
# iterate the grid | ||
for r in range(rows): | ||
for c in range(cols): | ||
if grid[r][c] == 1: | ||
fresh += 1 | ||
|
||
# add grid position of rotten orange | ||
if grid[r][c] == 2: | ||
queue.append((r, c)) | ||
|
||
# keep track of time | ||
time = 0 | ||
# directions in the form of x,y | ||
directions = ((1, 0), (0, 1), (-1, 0), (0, -1)) | ||
|
||
# while we have a queue of rotten oranges, and there are still fresh oranges. | ||
while queue and fresh > 0: | ||
for _ in range(len(queue)): | ||
row, col = queue.popleft() | ||
|
||
# check the 4 adjacent oranges of this rotten orange | ||
for (dr, dc) in directions: | ||
# position of adjacent orange | ||
r, c = row + dr, col + dc | ||
|
||
# check the adjacent orange is in bounds and fresh | ||
if r < 0 or r >= rows or c < 0 or c >= cols or grid[r][c] != 1: | ||
continue | ||
|
||
# they are fresh, therefore, it becomes rotten | ||
grid[r][c] = 2 | ||
fresh -= 1 | ||
|
||
# add new rotten orange to the queue, we won't reach it on this iteration, as we are only iterating | ||
# through the rotten from the last iteration | ||
queue.append((r, c)) | ||
|
||
# since we only looped through the rotten oranges inside the queue, and not the adjacent ones, we can increment | ||
# the time now, and on the next iteration we will check those adjacent ones | ||
time += 1 | ||
|
||
# if we turned all oranges rotten, return the time, else -1 | ||
return time if fresh == 0 else -1 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import unittest | ||
from . import oranges_rotting | ||
|
||
|
||
class RottingOrangesTestCase(unittest.TestCase): | ||
def test_1(self): | ||
"""should return 4 for grid = [[2,1,1],[1,1,0],[0,1,1]]""" | ||
grid = [[2, 1, 1], [1, 1, 0], [0, 1, 1]] | ||
expected = 4 | ||
actual = oranges_rotting(grid) | ||
self.assertEqual(expected, actual) | ||
|
||
def test_2(self): | ||
"""should return -1 for grid = [[2,1,1],[0,1,1],[1,0,1]]""" | ||
grid = [[2, 1, 1], [0, 1, 1], [1, 0, 1]] | ||
expected = -1 | ||
actual = oranges_rotting(grid) | ||
self.assertEqual(expected, actual) | ||
|
||
def test_3(self): | ||
"""should return 0 for grid = [[0,2]]""" | ||
grid = [[0, 2]] | ||
expected = 0 | ||
actual = oranges_rotting(grid) | ||
self.assertEqual(expected, actual) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |