1. Question
Givenn
nodes labeled from0
ton - 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:
Givenn = 5
andedges = [[0, 1], [1, 2], [3, 4]]
, return2
.
Example 2:
Copy 0 4
| |
1 --- 2 --- 3
Givenn = 5
andedges = [[0, 1], [1, 2], [2, 3], [3, 4]]
, return1
.
Note:
You can assume that no duplicate edges will appear inedges
. Since all edges are undirected,[0, 1]
is the same as[1, 0]
and thus will not appear together inedges
.
2. Implementation
(1) BFS
Copy class Solution {
public int countComponents ( int n , int [][] edges) {
if (n <= 1 ) {
return n;
}
// BFS
List < Set < Integer >> adjList = new ArrayList <>();
for ( int i = 0 ; i < n; i ++ ) {
adjList . add ( new HashSet <>());
}
for ( int [] edge : edges) {
adjList . get (edge[ 0 ]) . add (edge[ 1 ]);
adjList . 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;
Queue < Integer > queue = new LinkedList <>();
queue . add (i);
while ( ! queue . isEmpty ()) {
int curIndex = queue . remove ();
visited[curIndex] = true ;
for ( int nextIndex : adjList . get (curIndex)) {
if ( ! visited[nextIndex]) {
queue . add (nextIndex);
}
}
}
}
}
return count;
}
}
(2) DFS
Copy class Solution {
public int countComponents ( int n , int [][] edges) {
if (n <= 1 ) {
return n;
}
List < Set < Integer >> adjList = new ArrayList <>();
for ( int i = 0 ; i < n; i ++ ) {
adjList . add ( new HashSet <>());
}
boolean [] visited = new boolean [n];
for ( int [] edge : edges) {
adjList . get (edge[ 0 ]) . add (edge[ 1 ]);
adjList . get (edge[ 1 ]) . add (edge[ 0 ]);
}
int count = 0 ;
for ( int i = 0 ; i < n; i ++ ) {
if ( ! visited[i]) {
++ count;
searchComponentByDFS(i , adjList , visited) ;
}
}
return count;
}
public void searchComponentByDFS ( int node , List < Set < Integer >> adjList , boolean [] visited) {
visited[node] = true ;
for ( int nextNode : adjList . get (node)) {
if ( ! visited[nextNode]) {
searchComponentByDFS(nextNode , adjList , visited) ;
}
}
}
}
(3) Union Find
Copy class Solution {
public int countComponents ( int n , int [][] edges) {
if (n <= 1 ) {
return n;
}
UnionFind uf = new UnionFind(n) ;
for ( int [] edge : edges) {
uf . union (edge[ 0 ] , edge[ 1 ]);
}
return uf . count ;
}
class UnionFind {
int [] sets;
int [] size;
int count;
public UnionFind ( int n) {
sets = new int [n];
size = new int [n];
count = n;
for ( int i = 0 ; i < n; i ++ ) {
sets[i] = i;
size[i] = 1 ;
}
}
public int find ( int node) {
while (node != sets[node]) {
node = sets[node];
}
return node;
}
public void union ( int i , int j) {
int node1 = find(i) ;
int node2 = find(j) ;
if (node1 == node2) {
return ;
}
if (size[node1] < size[node2]) {
sets[node1] = node2;
size[node2] += size[node2];
}
else {
sets[node2] = node1;
size[node1] += size[node2];
}
-- count;
}
}
}
3. Time & Space Complexity
BFS: 时间复杂度O(n),空间复杂度O(n)
DFS: 时间复杂度O(n),空间复杂度O(n)
Union Find : 时间复杂度O(n), 空间复杂度O(n)