[LeetCode] 323. Number of Connected Components in an Undirected Graph
You have a graph of n
nodes. You are given an integer n
and an array edges
where edges[i] = [ai, bi]
indicates that there is an edge between ai
and bi
in the graph.
Return the number of connected components in the graph.
Example 1:
Input: n = 5, edges = [[0,1],[1,2],[3,4]] Output: 2
Example 2:
Input: n = 5, edges = [[0,1],[1,2],[2,3],[3,4]] Output: 1
Constraints:
1 <= n <= 2000
1 <= edges.length <= 5000
edges[i].length == 2
0 <= ai <= bi < n
ai != bi
- There are no repeated edges.
无向图中连通分量的数目。
你有一个包含 n 个节点的图。给定一个整数 n 和一个数组 edges ,其中 edges[i] = [ai, bi] 表示图中 ai 和 bi 之间有一条边。
返回 图中已连接分量的数目 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/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 node, List<List<Integer>> g) { 24 visited[node] = true; 25 for (int next : g.get(node)) { 26 if (!visited[next]) { 27 dfs(visited, next, 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 }
相关题目