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:
0 3
| |
1 --- 2 4
Given n = 5
and edges = [[0, 1], [1, 2], [3, 4]]
, return 2
.
Example 2:
0 4
| |
1 --- 2 --- 3
Given n = 5
and edges = [[0, 1], [1, 2], [2, 3], [3, 4]]
, return 1
.
思路1:用hashmap先构建邻接链表Adjacency List,然后用visited数组去记录访问过的点,然后BFS,queue为空的时候,就是count++的时候。注意如果刚开始就是孤岛,也是需要count++的。
思路2: 用DFS来做,同样要注意,如果点不在hashmap里面的时候要判断,这时也要count++;
class Solution {
public int countComponents(int n, int[][] edges) {
HashMap<Integer, HashSet<Integer>> graph = new HashMap<>();
for(int[] edge: edges) {
int a = edge[0];
int b = edge[1];
graph.putIfAbsent(a, new HashSet<>());
graph.putIfAbsent(b, new HashSet<>());
graph.get(a).add(b);
graph.get(b).add(a);
}
HashSet<Integer> visited = new HashSet<>();
int count = 0;
for(int i = 0; i < n; i++) {
if(!visited.contains(i)) {
// bfs(graph, i, visited);
dfs(graph, i, visited);
count++;
}
}
return count;
}
private void dfs(HashMap<Integer, HashSet<Integer>> graph, int node, HashSet<Integer> visited) {
if(visited.contains(node)) {
return;
}
visited.add(node);
if(graph.get(node) != null) {
for(Integer neighbor: graph.get(node)) {
dfs(graph, neighbor, visited);
}
}
}
private void bfs(HashMap<Integer, HashSet<Integer>> graph, int node, HashSet<Integer> visited) {
Queue<Integer> queue = new LinkedList<>();
queue.offer(node);
visited.add(node);
while(!queue.isEmpty()) {
Integer n = queue.poll();
if(graph.get(n) != null) {
for(Integer neighbor: graph.get(n)) {
if(!visited.contains(neighbor)) {
visited.add(neighbor);
queue.offer(neighbor);
}
}
}
}
}
}
思路3:用union find来做;天生就是union find的经典题;
class Solution {
public class UnionFind {
public int[] father;
public int count;
public UnionFind(int n) {
this.father = new int[n + 1];
for(int i = 0; i <= n; i++) {
father[i] = i;
}
this.count = n;
}
public int find(int x) {
int j = x;
while(father[j] != j) {
j = father[j];
}
// path compression;
while(x != j) {
int fx = father[x];
father[x] = j;
x = fx;
}
return j;
}
public void union(int a, int b) {
int root_a = find(a);
int root_b = find(b);
if(root_a != root_b) {
father[root_a] = root_b;
count--;
}
}
}
public int countComponents(int n, int[][] edges) {
UnionFind uf = new UnionFind(n);
for(int[] edge: edges) {
int a = edge[0];
int b = edge[1];
if(uf.find(a) != uf.find(b)) {
uf.union(a, b);
}
}
return uf.count;
}
}