[LintCode] Connected Component in Undirected Graph

Find the number connected component in the undirected graph. Each node in the graph contains a label and a list of its neighbors. (a connected component (or just component) of an undirected graph is a subgraph in which any two vertices are connected to each other by paths, and which is connected to no additional vertices in the supergraph.)

Each connected component should sort by label.

 
Example

Given graph:

A------B  C
 \     |  | 
  \    |  |
   \   |  |
    \  |  |
      D   E

Return {A,B,D}, {C,E}. Since there are two connected component which is {A,B,D}, {C,E}

 

Solution 1. BFS

Algorithm.

Iterate all nodes in the input graph and do the following.

1. For each unvisited graph node s, do a bfs starting from it and add all nodes that can be reached from s to a list as one connected component. Add each visited nodes to a global set that tracks which nodes have been visited.

2. Sort each connected component.

 

 1 /**
 2  * Definition for Undirected graph.
 3  * class UndirectedGraphNode {
 4  *     int label;
 5  *     ArrayList<UndirectedGraphNode> neighbors;
 6  *     UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
 7  * };
 8  */
 9 
10 //Algorithm 1. bfs 
11 public class Solution {
12     public List<List<Integer>> connectedSet(ArrayList<UndirectedGraphNode> nodes) {
13         List<List<Integer>> results = new ArrayList<List<Integer>>();
14         if(nodes == null || nodes.size() == 0)
15         {
16             return results;
17         }
18         Set<UndirectedGraphNode> visited = new HashSet<UndirectedGraphNode>();
19         //bfs on each node to get all the connected components
20         for(UndirectedGraphNode node : nodes)   
21         {
22             if(!visited.contains(node))
23             {
24                 bfs(node, visited, results);
25             }
26         }
27         return results;
28     }
29     private void bfs(UndirectedGraphNode node, 
30                     Set<UndirectedGraphNode> visited,
31                     List<List<Integer>> results)
32     {
33         ArrayList<Integer> comp = new ArrayList<Integer>();
34         Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
35         queue.offer(node);
36         visited.add(node);
37         comp.add(node.label);
38         
39         while(!queue.isEmpty())
40         {
41             UndirectedGraphNode curr = queue.poll();
42             for(UndirectedGraphNode neighbor : curr.neighbors)
43             {
44                 if(!visited.contains(neighbor))
45                 {
46                     queue.offer(neighbor);
47                     visited.add(neighbor);
48                     comp.add(neighbor.label);
49                 }
50             }
51         }
52         Collections.sort(comp);
53         results.add(comp);
54     }
55 }

 

 

Solution 2. Union Find

Algorithm.

1. Add each node to a union find data structure and connect these nodes based on the graph edges. A hash map is better suited for the union find since the input graph nodes' labels do not necessarily starts from 0 and are not guranteed to be consecutive. 

2. Iterate through the uf and create a mapping bewteen a root label and its represented node labels. Sort each map value and add it to the final result.

 

 1 //Algorithm 2. Union Find
 2 public class Solution {
 3     class UnionFind {
 4         private HashMap<Integer, Integer> father = null;
 5         public UnionFind(HashSet<Integer> labels){
 6             father = new HashMap<Integer, Integer>();
 7             for(Integer i : labels){
 8                 father.put(i, i);
 9             }
10         }
11         public int find(int x){
12             int parent = father.get(x);
13             while(parent != father.get(parent)){
14                 parent = father.get(parent);
15             }
16             
17             //compress path
18             int next;
19             while(x != father.get(x)){
20                 next = father.get(x);
21                 father.put(x, parent);
22                 x = next;
23             }
24             return parent;
25         }
26         public void connect(int x, int y){
27             int root_x = find(x);
28             int root_y = find(y);
29             if(root_x != root_y){
30                 father.put(root_x, root_y);
31             }
32         }
33         
34     }
35     public List<List<Integer>> connectedSet(ArrayList<UndirectedGraphNode> nodes) {
36         List<List<Integer>> results = new ArrayList<List<Integer>>();
37         if(nodes == null || nodes.size() == 0){
38             return results;
39         }
40         //store all nodes' labels in a hash set
41         HashSet<Integer> nodeLabels = new HashSet<Integer>();
42         for(UndirectedGraphNode node : nodes){
43             nodeLabels.add(node.label);
44             for(UndirectedGraphNode neighbor : node.neighbors){
45                 nodeLabels.add(neighbor.label);
46             }
47         }
48         //connect all nodes based on the edges
49         UnionFind uf = new UnionFind(nodeLabels);
50         for(UndirectedGraphNode node : nodes){
51             for(UndirectedGraphNode neighbor : node.neighbors){
52                 uf.connect(node.label, neighbor.label);
53             }
54         }
55         getAllCC(nodeLabels, uf, results);
56         return results;
57     }
58     private void getAllCC(HashSet<Integer> nodeLabels, UnionFind uf, List<List<Integer>> results){
59         //key: root representative of each connected component
60         //value: connected component
61         HashMap<Integer, List<Integer>> cc = new HashMap<Integer, List<Integer>>();
62         for(int i : nodeLabels){
63             int root = uf.find(i);
64             if(!cc.containsKey(root)){
65                 cc.put(root, new ArrayList<Integer>());
66             }
67             cc.get(root).add(i);
68         }
69         //sort answers
70         for(List<Integer> comp : cc.values()){
71             Collections.sort(comp);
72             results.add(comp);
73         }
74     }
75 }

 

 

Related Problems

Graph Valid Tree

Find the Weak Connected Component in the Directed Graph

转载于:https://www.cnblogs.com/lz87/p/7496951.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值