# **Leetcode筆記(Rotting Oranges)**
:::info
:information_source: 題目 : Rotting Oranges, 類型 : graph , 等級 : medium
日期 : 2023/05/16,2023/07/14,2024/02/14,2024/09/25
:::
### 嘗試
時間複雜度:假設矩陣中有N個單元格,其中有M個腐爛的橘子。在最壞的情況下,所有的腐爛橘子都需要進行BFS遍歷,而每個單元格最多被訪問一次。
因此,總的時間複雜度為O(M*N)。
空間複雜度方面,你使用了一個佇列q來存儲腐爛的橘子。由於最多只會存儲M個腐爛橘子,所以佇列的最大長度為M。
此外,你還使用了一個集合visited來記錄已經訪問過的橘子的坐標。在最壞的情況下,所有的單元格都需要被訪問一次,所以集合visited最多佔用N個單元格的額外空間。
因此,總的空間複雜度為O(M+N)。 Solution:
def orangesRotting(self, grid: List[List[int]]) -> int:
# 適用bfs 因為是類似一層一層往外看
# 而不是先走到最深處
m, n = len(grid), len(grid[0])
```python
class Solution:
def orangesRotting(self, grid: List[List[int]]) -> int:
# 適用bfs 因為是類似一層一層往外看
# 而不是先走到最深處
m, n = len(grid), len(grid[0])
dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)]
q = deque()
visited = set()
fresh_ori, fresh_step = 0, 0 # 紀錄bfs次數
fresh = 0 # 真實為1的水果次數
for r in range(m):
for c in range(n):
if grid[r][c] == 2:
q.append((r, c))
elif grid[r][c] == 1:
fresh += 1
# 完全沒有正常水果
if fresh == 0:
return 0
while q:
step = len(q)
# 把這一輪內的q先完全清空
# 這樣就可以記錄"輪"的次數
for i in range(step):
row, col = q.popleft()
visited.add((row, col))
for dr, dc in dirs:
nr, nc = dr + row, dc + col
if 0 <= nr < m and 0 <= nc < n and (nr, nc) not in visited and grid[nr][nc] == 1:
visited.add((nr, nc))
q.append((nr, nc))
fresh_ori += 1
fresh_step += 1
if fresh_ori == fresh:
return fresh_step - 1 # 第一輪不算
else:
return -1
```
2023/07/13
因為需要算階層數,所以用bfs的方法,創造一個deque,注意visited是在通過下面if條件後才加入
```python
class Solution:
def orangesRotting(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)]
q = deque()
visited = set()
fresh, becoRotten, step = 0, 0, 0
# 統計腐爛與新鮮的
for r in range(m):
for c in range(n):
if grid[r][c] == 2:
q.append((r, c))
if grid[r][c] == 1:
fresh += 1
# 沒有新鮮的直接返回
if fresh == 0:
return 0
while q:
length = len(q)
for _ in range(length):
r, c = q.popleft()
for dr, dc in dirs:
nr, nc = r + dr, c + dc
if 0 <= nr < m and 0 <= nc < n and (nr, nc) not in visited and grid[nr][nc] == 1:
q.append((nr, nc))
visited.add((nr, nc)) # 這時候就要加入visited 避免重複加入 使step計算上有錯誤
becoRotten += 1
step += 1
if becoRotten == fresh:
return step - 1 # 第一輪不算
return -1
```
2023/12/09
```python
"""
count the number of fresh
q = deque()
start from the rotten
visited -> store o already rotten
while q:
keep pop from q
1. check four dirrection
2. add more o (next layer) to q
3. add o to visited
track the layer
check if fresh == len(visited)
"""
import collections
class Solution:
def orangesRotting(self, grid: List[List[int]]) -> int:
n, m = len(grid), len(grid[0])
# init BFS
q = deque()
visited = set()
# count the fresh orange
fresh = 0
for r in range(n):
for c in range(m):
if grid[r][c] == 1:
fresh += 1
elif grid[r][c] == 2:
q.append((r, c))
visited.add((r, c))
if fresh == 0:
return 0
dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)]
step = 0
# start BFS
while q:
layer = len(q)
for _ in range(layer):
r, c = q.popleft()
for dr, dc in dirs:
nr, nc = r + dr, c + dc
if 0 <= nr < n and 0 <= nc < m and (nr, nc) not in visited and grid[nr][nc] == 1:
q.append((nr, nc))
visited.add((nr, nc))
fresh -= 1
print(fresh)
step += 1
if fresh == 0:
return step - 1
return -1
```
2024/02/14
```python
class Solution:
def orangesRotting(self, grid: List[List[int]]) -> int:
n, m = len(grid), len(grid[0])
dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)]
fresh_to_rotten, fresh = 0, 0
q = deque()
visited = set()
# collection the rotten orange
for r in range(n):
for c in range(m):
if grid[r][c] == 2:
q.append((r, c))
visited.add((r, c))
if grid[r][c] == 1:
fresh += 1
# special case
if fresh == 0:
return 0
step = 0
while q:
length = len(q)
for _ in range(length):
rotten_r, rotten_c = q.popleft()
for dr, dc in dirs:
new_r, new_c = rotten_r + dr, rotten_c + dc
if 0 <= new_r < n and 0 <= new_c < m and grid[new_r][new_c] == 1 and (new_r, new_c) not in visited:
q.append((new_r, new_c))
visited.add((new_r, new_c))
fresh_to_rotten += 1
step += 1
if fresh_to_rotten == fresh:
return step - 1
else:
return -1
```
2024/09/25
```python
class Solution:
def orangesRotting(self, grid: List[List[int]]) -> int:
n, m = len(grid), len(grid[0])
fresh, normal = 0, 0
q = deque()
visited = set()
dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]
for r in range(n):
for c in range(m):
if grid[r][c] == 0:
normal += 1
if grid[r][c] == 1:
fresh += 1
if grid[r][c] == 2:
q.append((r, c))
visited.add((r, c))
if normal == n * m: # 處理都是0
return 0
fresh_count = 0
step = 0
while q:
l = len(q)
for _ in range(l):
r, c = q.popleft()
for dr, dc in dirs:
nr, nc = r + dr, c + dc
if 0 <= nr < n and 0 <= nc < m and (nr, nc) not in visited and grid[nr][nc] == 1:
fresh_count += 1
q.append((nr, nc))
visited.add((nr, nc))
step += 1
if fresh_count == fresh:
return step - 1
else:
return -1
```
---
### **優化**
```python
```
---
**:warning: 錯誤語法**
:::warning
:::
**:thumbsup:學習**
:::success
:::
**思路**
**講解連結**
Provided by. NeetCode
###### tags: `graph` `medium` `leetcode`