[LeetCode] 323. Number of Connected Components in an Undirected Graph

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 and edges = [[0, 1], [1, 2], [3, 4]]

     0          3
     |          |
     1 --- 2    4 

Output: 2

Example 2:

Input: n = 5 and edges = [[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 }

相关题目

261. Graph Valid Tree

323. Number of Connected Components in an Undirected Graph

547. Friend Circles

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/14197652.html