无向图中连通分量的数目
难度:
标签:
题目描述
代码结果
运行时间: 26 ms, 内存: 17.4 MB
/*
* 思路:
* 给定一个无向图,要求计算图中的连通分量的数量。
* 使用Java Stream API处理邻接表创建和节点遍历。
* 使用DFS进行图的遍历。
*/
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class NumberOfConnectedComponentsStream {
public int countComponents(int n, int[][] edges) {
// 创建图的邻接表表示
List<List<Integer>> graph = IntStream.range(0, n)
.mapToObj(i -> new ArrayList<Integer>())
.collect(Collectors.toList());
Arrays.stream(edges).forEach(edge -> {
graph.get(edge[0]).add(edge[1]);
graph.get(edge[1]).add(edge[0]);
});
// 记录访问过的节点
boolean[] visited = new boolean[n];
int count = 0;
// 遍历每个节点
for (int i = 0; i < n; i++) {
if (!visited[i]) {
count++;
dfs(graph, visited, i);
}
}
return count;
}
// 深度优先搜索(DFS)方法
private void dfs(List<List<Integer>> graph, boolean[] visited, int node) {
visited[node] = true;
graph.get(node).stream()
.filter(neighbor -> !visited[neighbor])
.forEach(neighbor -> dfs(graph, visited, neighbor));
}
}
解释
方法:
这个题解使用深度优先搜索(DFS)来解决无向图中连通分量的数目问题。首先,通过遍历所有边构建图的邻接表表示。然后,对于每个节点,如果它还没有被访问过,就将连通分量的计数器加1,并从该节点开始进行DFS遍历,标记所有与之相连的节点为已访问。最终,连通分量的总数就是DFS遍历的次数。
时间复杂度:
O(V+E)
空间复杂度:
O(V+E)
代码细节讲解
🦆
如何确保通过构建的邻接表能够正确反映无向图中所有节点之间的关系,特别是对于孤立节点的处理?
▷🦆
在DFS遍历中,如果遇到具有大量节点和边的密集图,递归调用栈可能存在溢出的风险吗?存在的话,如何优化以避免这种情况?
▷🦆
在DFS函数中,递归之前没有特别检查`n`是否存在于图`g`中,这是否会影响算法的执行或导致错误?
▷🦆
在处理连通分量的计数时,代码是如何确保每个新开始的DFS遍历都是从一个新的连通分量开始的?
▷相关问题
岛屿数量
给你一个由 '1'
(陆地)和 '0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [ ["1","1","1","1","0"], ["1","1","0","1","0"], ["1","1","0","0","0"], ["0","0","0","0","0"] ] 输出:1
示例 2:
输入:grid = [ ["1","1","0","0","0"], ["1","1","0","0","0"], ["0","0","1","0","0"], ["0","0","0","1","1"] ] 输出:3
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j]
的值为'0'
或'1'
省份数量
有 n
个城市,其中一些彼此相连,另一些没有相连。如果城市 a
与城市 b
直接相连,且城市 b
与城市 c
直接相连,那么城市 a
与城市 c
间接相连。
省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。
给你一个 n x n
的矩阵 isConnected
,其中 isConnected[i][j] = 1
表示第 i
个城市和第 j
个城市直接相连,而 isConnected[i][j] = 0
表示二者不直接相连。
返回矩阵中 省份 的数量。
示例 1:

输入:isConnected = [[1,1,0],[1,1,0],[0,0,1]] 输出:2
示例 2:

输入:isConnected = [[1,0,0],[0,1,0],[0,0,1]] 输出:3
提示:
1 <= n <= 200
n == isConnected.length
n == isConnected[i].length
isConnected[i][j]
为1
或0
isConnected[i][i] == 1
isConnected[i][j] == isConnected[j][i]