Given n
nodes labeled from 0
to n - 1
and a list of undirected edges (each edge is a pair of nodes), write a function to find the number of connected components in an undirected graph.
Example 1:
Input:n = 5
andedges = [[0, 1], [1, 2], [3, 4]]
0 3 | | 1 --- 2 4 Output: 2
Example 2:
Input:n = 5
andedges = [[0, 1], [1, 2], [2, 3], [3, 4]]
0 4 | | 1 --- 2 --- 3 Output: 1
Note:
You can assume that no duplicate edges will appear in edges
. Since all edges are undirected, [0, 1]
is the same as [1, 0]
and thus will not appear together in edges
.
无向图中连通分量的数目。
给定编号从
0
到n-1
的n
个节点和一个无向边列表(每条边都是一对节点),请编写一个函数来计算无向图中连通分量的数目。注意:
你可以假设在 edges 中不会出现重复的边。而且由于所以的边都是无向边,[0, 1] 与 [1, 0] 相同,所以它们不会同时在 edges 中出现。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-connected-components-in-an-undirected-graph
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题可以归结为flood fill类型的题,我这里给出三种解法,分别是BFS, DFS和并查集union find。其中DFS和并查集是需要重点掌握的,BFS的复杂度略高。
BFS
时间O(n^2)
空间O(n)
Java实现
1 class Solution { 2 public int countComponents(int n, int[][] edges) { 3 int count = 0; 4 List<List<Integer>> g = new ArrayList<>(); 5 boolean[] visited = new boolean[n]; 6 for (int i = 0; i < n; i++) { 7 g.add(new ArrayList<>()); 8 } 9 for (int[] e : edges) { 10 g.get(e[0]).add(e[1]); 11 g.get(e[1]).add(e[0]); 12 } 13 14 for (int i = 0; i < n; i++) { 15 if (!visited[i]) { 16 count++; 17 Queue<Integer> queue = new LinkedList<>(); 18 queue.offer(i); 19 while (!queue.isEmpty()) { 20 int index = queue.poll(); 21 visited[index] = true; 22 for (int next : g.get(index)) { 23 if (!visited[next]) { 24 queue.offer(next); 25 } 26 } 27 } 28 } 29 } 30 return count; 31 } 32 }
DFS
时间O(n^2)
空间O(n)
Java实现
1 class Solution { 2 public int countComponents(int n, int[][] edges) { 3 int count = 0; 4 List<List<Integer>> g = new ArrayList<>(); 5 boolean[] visited = new boolean[n]; 6 for (int i = 0; i < n; i++) { 7 g.add(new ArrayList<>()); 8 } 9 for (int[] e : edges) { 10 g.get(e[0]).add(e[1]); 11 g.get(e[1]).add(e[0]); 12 } 13 14 for (int i = 0; i < n; i++) { 15 if (!visited[i]) { 16 count++; 17 dfs(visited, i, g); 18 } 19 } 20 return count; 21 } 22 23 private void dfs(boolean[] visited, int index, List<List<Integer>> g) { 24 visited[index] = true; 25 for (int i : g.get(index)) { 26 if (!visited[i]) { 27 dfs(visited, i, g); 28 } 29 } 30 } 31 }
Union Find
时间O(V * E)
空间O(n)
Java实现
1 class Solution { 2 public int countComponents(int n, int[][] edges) { 3 int count = n; 4 int[] parents = new int[n]; 5 for (int i = 0; i < n; i++) { 6 parents[i] = i; 7 } 8 for (int[] edge : edges) { 9 int p = find(parents, edge[0]); 10 int q = find(parents, edge[1]); 11 if (p != q) { 12 parents[p] = q; 13 count--; 14 } 15 } 16 return count; 17 } 18 19 private int find(int[] parents, int i) { 20 while (parents[i] != i) { 21 parents[i] = parents[parents[i]]; // 路径压缩 22 i = parents[i]; 23 } 24 return i; 25 } 26 }
相关题目