給定一個 m x n 的地圖矩陣,1 代表水池,0 代表陸地。相鄰(上下左右)的水池視為同一個水池。求地圖中水池的總數。這是典型的「島嶼數量」問題,核心在於圖的連通分量統計。
DFS 利用遞歸或棧將一個水池所有相連的 '1' 標記為 '0'(或訪問標記),每發起一次 DFS,計數器加一。提供兩種寫法:
void DFS(int i, int j) {
if(map[i][j-1]) { map[i][j-1]=0; DFS(i, j-1); }
if(map[i][j+1]) { map[i][j+1]=0; DFS(i, j+1); }
if(map[i-1][j]) { map[i-1][j]=0; DFS(i-1, j); }
if(map[i+1][j]) { map[i+1][j]=0; DFS(i+1, j); }
}
int f[4][2] = {{-1,0}, {1,0}, {0,1}, {0,-1}};
void DFS(int i, int j) {
map[i][j] = 0;
for(int k=0; k<4; k++) {
int ni = i + f[k][0], nj = j + f[k][1];
if(map[ni][nj] == 1) DFS(ni, nj);
}
}
BFS 使用隊列模擬「波浪式」擴散,避免遞歸棧溢出風險,適合大數據範圍。
struct Node { int x, y; };
queue q;
void BFS(int i, int j) {
q.push({i, j}); map[i][j] = 0;
while(!q.empty()) {
Node cur = q.front(); q.pop();
for(int k=0; k<4; k++) {
int nx = cur.x + f[k][0], ny = cur.y + f[k][1];
if(map[nx][ny]) { map[nx][ny] = 0; q.push({nx, ny}); }
}
}
}
[200][200] 足夠應對 m,n < 100 的限制,邊界處理可通過擴展邊界或判斷坐標合法性解決。