DFS解法
class Solution:
dir = [(-1,0),(1,0),(0,-1),(0,1)]
def dfs(self,grid,x,y):
if x < 0 or x >= len(grid) or y < 0 or y >= len(grid[0]) or grid[x][y] != 1:
return 0
grid[x][y] = 0
ans = 1
for (dx,dy) in self.dir:
ans += self.dfs(grid,x+dx,y+dy)
return ans
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ans = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
ans = max(ans, self.dfs(grid,i,j))
return ans
為什麼要遍歷整個網格?
島嶼可能是多個分離的區域
-
一個二維網格可能包含多個島嶼,它們彼此不相連。我們不能假設只用一個起點就能發現整個網格中的所有島嶼,因為每個島嶼的起點可能散佈在不同的位置。
-
示例:
grid = [ [1, 0, 0, 1],
[1, 0, 1, 0],
[0, 0, 1, 0]
]
在上面的示例中有 3 個獨立的島嶼:一個位於左上角,一個位於中部,一個位於右下角。因此,必須遍歷整個網格以找到所有的島嶼。
DFS 需要從每個可能的起點出發 當你遍歷到某個位置 (i, j)
並且發現它是陸地(1
),這意味著它可能是島嶼的一部分。於是你需要呼叫 DFS 來探索與這個位置相連的所有陸地單元格,以計算這個島嶼的面積。
為什麼將訪問過的陸地變為0
在每次 DFS 呼叫中,你會將訪問過的陸地標記為水(將 1
變成 0
),這樣可以避免重複計算已經處理過的島嶼。
其實也可以變為 -1 或者任何不為1的數
當然也可以新建一個列表 visited 記錄下來每一個訪問過的地方,但是這樣會浪費空間
BFS解法
class Solution:
dir = [(-1,0),(1,0),(0,-1),(0,1)]
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ans = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
queue = [(i,j)]
count = 0
while len(queue) > 0:
x,y = queue.pop(0)
if x < 0 or x >= len(grid) or y < 0 or y >= len(grid[0]) or grid[x][y] != 1:
continue
grid[x][y] = -1
count += 1
for dx,dy in self.dir:
nx,ny = x+dx,y+dy
queue.append((nx,ny))
ans = max(ans,count)
return ans
為什麼將檢查放在四個方向迴圈之後是錯誤的
如果你把檢查邏輯放在四個方向迴圈之後,程式碼可能會變成這樣:
for dx, dy in self.dir:
nx, ny = x + dx, y + dy
# 假設這裡再檢查是否越界或是否訪問過
if nx < 0 or nx >= len(grid) or ny < 0 or ny >= len(grid[0]) or grid[nx][ny] != 1:
continue
queue.append((nx, ny))
這樣處理代表在彈出節點 (x, y)
後,你已經預設地將這個節點當作有效節點,甚至可能在 count += 1
之前錯誤地處理了它。例如第一次新增的節點,你並不知道他是否有效,但你只在這裡進行判斷就會導致漏掉一個判斷。
這裡你可以使用控制變數法,將這段程式碼加入進去發現還是正確的,但是如果去掉while迴圈下的判斷就會發生錯誤
class Solution:
dir = [(-1,0),(1,0),(0,-1),(0,1)]
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ans = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
queue = [(i,j)]
count = 0
while len(queue) > 0:
x,y = queue.pop(0)
if x < 0 or x >= len(grid) or y < 0 or y >= len(grid[0]) or grid[x][y] != 1:
continue
grid[x][y] = -1
count += 1
for dx,dy in self.dir:
nx,ny = x+dx,y+dy
if nx < 0 or nx >= len(grid) or ny < 0 or ny >= len(grid[0]) or grid[nx][ny] != 1:
continue
queue.append((nx,ny))
ans = max(ans,count)
return ans