想法:
在迴圈中從 queue 取出座標,檢查四個方向(上下左右),凡是 '1' 就標成 '0' 並加入 queue。
當 queue 清空時,代表整座島被處理完畢,直到全部掃完。
優勢:
不會有遞迴深度問題;每格只會被加入/處理一次
程式碼:
class Solution {
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) return 0;
int m = grid.length, n = grid[0].length;
int count = 0;
int[] dr = {-1, 1, 0, 0};
int[] dc = {0, 0, -1, 1};
Deque<int[]> queue = new ArrayDeque<>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
count++;
// 標記並加入 queue(標記在加入時做,避免重複加入)
grid[i][j] = '0';
queue.offerLast(new int[]{i, j});
// BFS:把整座島淹成 '0'
while (!queue.isEmpty()) {
int[] cur = queue.pollFirst();
int r = cur[0], c = cur[1];
for (int k = 0; k < 4; k++) {
int nr = r + dr[k];
int nc = c + dc[k];
// 檢查邊界與是否為陸地
if (nr >= 0 && nr < m && nc >= 0 && nc < n && grid[nr][nc] == '1') {
grid[nr][nc] = '0'; // 標記為已訪問
queue.offerLast(new int[]{nr, nc}); // 加入 queue
}
}
}
}
}
}
return count;
}
}
比較:
DFS(深度優先搜尋)
BFS(廣度優先搜尋)