323. Number of Connected Components in an Undirected Graph

Description

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:

graph

Given n = 5 and edges = [[0, 1], [1, 2], [3, 4]], return 2.

Example 2:

graph

Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [3, 4]], return 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.

Solution

DFS

用Map来保存节点连接的关系。注意set.add返回的boolean表示是否成功加入到set中,可以用来精简代码。

class Solution {
    public int countComponents(int n, int[][] edges) {
        if (n < 2 || edges.length < 1) {
            return n;
        }
        
        Map> map = new HashMap<>();
        for (int i = 0; i < n; ++i) {
            map.put(i, new LinkedList<>());
        }
        
        for (int[] edge : edges) {
            map.get(edge[0]).add(edge[1]);
            map.get(edge[1]).add(edge[0]);
        }
        
        Set visited = new HashSet<>();
        int count = 0;
        
        for (int i = 0; i < n; ++i) {
            if (visited.add(i)) {   // i has not been handled
                dfsCountComponents(i, map, visited);
                ++count;
            }
        }
        
        return count;
    }
    
    public void dfsCountComponents(
        int i, Map> map, Set visited) {
        for (Integer neighbor : map.get(i)) {
            if (visited.add(neighbor)) {
                dfsCountComponents(neighbor, map, visited);
            }
        }
    }
}

BFS

class Solution {
    public int countComponents(int n, int[][] edges) {
        if (n < 2 || edges.length < 1) {
            return n;
        }
        
        Map> map = new HashMap<>();
        for (int i = 0; i < n; ++i) {
            map.put(i, new LinkedList<>());
        }
        
        for (int[] edge : edges) {
            map.get(edge[0]).add(edge[1]);
            map.get(edge[1]).add(edge[0]);
        }
        
        Set visited = new HashSet<>();
        Queue queue = new LinkedList<>();
        int count = 0;
        
        for (int i = 0; i < n; ++i) {
            if (visited.add(i)) {   // visited first then add to queue
                queue.add(i);

                while (!queue.isEmpty()) {
                    Integer curr = queue.poll();
                    for (Integer neighbor : map.get(curr)) {
                        if (visited.add(neighbor)) {
                           queue.add(neighbor);
                        }
                    }
                }

                ++count;                
            }
        }
        
        return count;
    }
}

Union-Find, time O(n), space O(n)

class Solution {
    public int countComponents(int n, int[][] edges) {
        if (n < 1 || edges == null) {
            return 0;
        }
        
        UnionFind uf = new UnionFind(n);
        for (int[] edge : edges) {
            uf.union(edge[0], edge[1]);
        }
        
        Set components = new HashSet<>();
        for (int i = 0; i < n; ++i) {
            components.add(uf.find(i));
        }
        
        return components.size();
    }
    
    class UnionFind {
        int[] parent;
        
        public UnionFind(int n) {
            parent = new int[n];
            for (int i = 0; i < n; ++i) {
                parent[i] = i;
            }
        }
        
        public int find(int x) {
            if (parent[x] != x) {
                parent[x] = find(parent[x]);
            }
            return parent[x];
        }
        
        public void union(int x, int y) {
            parent[find(x)] = parent[find(y)];
        }
    }
}

也可以像下面这样,首先假设每个节点各成一个component,那么起初总共有n 个components。然后边遍历edges边执行union操作,执行成功一次意味着有两个component连起来了,那么--componentCount即可。

class Solution {
    public int countComponents(int n, int[][] edges) {
        if (n < 1 || edges == null) {
            return 0;
        }
        
        int[] parent = new int[n];
        for (int i = 0; i < n; ++i) {
            parent[i] = i;
        }
        
        int components = n;
        for (int[] edge : edges) {
            int xset = find(parent, edge[0]);
            int yset = find(parent, edge[1]);
            
            if (xset != yset) {     // union two components
                parent[xset] = yset;
                --components;
            }
        }
        
        return components;
    }
    
    public int find(int[] parent, int x) {
        if (parent[x] != x) {
            parent[x] = find(parent, parent[x]);
        }
        return parent[x];
    }
}

你可能感兴趣的:(323. Number of Connected Components in an Undirected Graph)