1. 岛屿数量中 DFS、BFS、并查集三种解法在递归深度与并发场景下的取舍?
求解岛屿数量,比较 DFS、BFS、并查集三种解法在递归深度与并发场景下的取舍?
- DFS 递归深浅、栈溢出风险
- BFS 队列、无栈溢出
- 并查集可并行合并
DFS:递归洪泛,代码简洁,但递归深度可达网格大小,大网格可能栈溢出(可改显式栈)。BFS:用队列层序洪泛,无递归栈溢出风险,适合大网格。并查集:把每个陆地格子作为节点,相邻陆地合并,最后统计连通分量数;适合并行(各区域可独立合并后 union),也能处理增量/动态连接。取舍:网格小用 DFS 最简;网格大担心栈深用 BFS;需并行或动态维护用并查集。三者时间都 O(n×m),并查集空间略大(需 parent 数组)。
三种解法是"连通分量"的三种视角:DFS/BFS 是显式/隐式洪泛,并查集是离线合并。DFS 的栈深是隐患,BFS 省心,并查集利于并行。选型取决于网格规模与并发需求。
// 并查集法
int numIslandsUF(char[][] g) {
int m = g.length, n = g[0].length;
int[] parent = new int[m * n];
Arrays.fill(parent, -1);
int cnt = 0;
for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) {
if (g[i][j] == '1') { parent[i * n + j] = i * n + j; cnt++; }
}
for (int i = 0; i < m; i++) for (int j = 0; j < n; j++)
if (g[i][j] == '1') {
if (i + 1 < m && g[i + 1][j] == '1') if (union(parent, i * n + j, (i + 1) * n + j)) cnt--;
if (j + 1 < n && g[i][j + 1] == '1') if (union(parent, i * n + j, i * n + j + 1)) cnt--;
}
return cnt;
}