994. 腐烂的橘子
class OrangesRotting:
"""
994. 腐烂的橘子
https://leetcode.cn/problems/rotting-oranges/description/
"""
def solution(self, grid: List[List[int]]) -> int:
"""
BFS
时间复杂度 O(M*N)
空间复杂度 O(M*N)
:param grid:
:return:
"""
row, col, time = len(grid), len(grid[0]), 0
directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
queue = []
# add the rotten orange to the queue
for i in range(row):
for j in range(col):
if grid[i][j] == 2:
queue.append((i, j, time))
# bfs
while queue:
i, j, time = queue.pop(0)
for di, dj in directions:
if 0 <= i + di < row and 0 <= j + dj < col and grid[i + di][j + dj] == 1:
grid[i + di][j + dj] = 2
queue.append((i+di, j+dj, time+1))
# if there are still fresh oranges, return -1
for row in grid:
if 1 in row:
return -1
return time
def solution1(self, grid: List[List[int]]) -> int:
"""
DFS
时间复杂度 O((M*N)^2)
空间复杂度 O(M*N)
:param grid:
:return:
"""
rows, cols = len(grid), len(grid[0])
fresh = set()
rotten = set()
# Find positions of fresh and rotten oranges
for r in range(rows):
for c in range(cols):
if grid[r][c] == 1:
fresh.add((r, c))
elif grid[r][c] == 2:
rotten.add((r, c))
def dfs(r, c, minutes):
# Check if position is valid and orange is fresh
if r < 0 or r >= rows or c < 0 or c >= cols or grid[r][c] != 1:
return
# If the current rotting time is less than the stored value
# update it and continue DFS to adjacent oranges
if (r, c) in fresh and minutes < self.time_to_rot.get((r, c), float('inf')):
self.time_to_rot[(r, c)] = minutes
dfs(r + 1, c, minutes + 1)
dfs(r - 1, c, minutes + 1)
dfs(r, c + 1, minutes + 1)
dfs(r, c - 1, minutes + 1)
# Dictionary to store the time taken to rot each fresh orange
self.time_to_rot = {}
# Start DFS from each rotten orange
for r, c in rotten:
dfs(r + 1, c, 1)
dfs(r - 1, c, 1)
dfs(r, c + 1, 1)
dfs(r, c - 1, 1)
# If there are fresh oranges that never rot, return -1
if len(fresh) != len(self.time_to_rot):
return -1
# Return the maximum time taken to rot any fresh orange
return max(self.time_to_rot.values(), default=0)