原题链接在这里:http://www.lintcode.com/en/problem/find-the-weak-connected-component-in-the-directed-graph/
题目:
Find the number Weak Connected Component in the directed graph. Each node in the graph contains a label and a list of its neighbors. (a connected set of a directed graph is a subgraph in which any two vertices are connected by direct edge path.)
Notice
Sort the element in the set in increasing order
Given graph:
A----->B C
| |
| |
| |
v v
->D E <- F
Return {A,B,D}, {C,E,F}
. Since there are two connected component which are {A,B,D} and {C,E,F}
题解:
是Union Find类题目. 用HashMap 的key -> value对应关系来维护child -> parent关系.
对于每一组node -> neighbor都当成 child -> parent的关系利用forest union起来.
再用resHashMap 来记录每一个root 和 这个root对应的所有children, 包括root本身, 对应关系.
最后把resHashMap.values() 挨个排序后加到res中.
Time Complexity: O(nlogn). n=hs.size(). 就是所有点的个数.
得到hs用了O(n). forest union用了 O(nlogn). 得到resHashMap用了O(nlogn). 得到res用了O(nlogn).
Space: O(n).
AC Java:
1 /** 2 * Definition for Directed graph. 3 * class DirectedGraphNode { 4 * int label; 5 * ArrayList<DirectedGraphNode> neighbors; 6 * DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); } 7 * }; 8 */ 9 public class Solution { 10 public List<List<Integer>> connectedSet2(ArrayList<DirectedGraphNode> nodes) { 11 12 List<List<Integer>> res = new ArrayList<List<Integer>>(); 13 if(nodes == null || nodes.size() == 0){ 14 return res; 15 } 16 17 HashSet<Integer> hs = new HashSet<Integer>(); 18 for(DirectedGraphNode node : nodes){ 19 hs.add(node.label); 20 for(DirectedGraphNode neigh : node.neighbors){ 21 hs.add(neigh.label); 22 } 23 } 24 25 UnionFind forest = new UnionFind(hs); 26 for(DirectedGraphNode node : nodes){ 27 for(DirectedGraphNode neigh : node.neighbors){ 28 forest.union(node.label, neigh.label); 29 } 30 } 31 32 HashMap<Integer, List<Integer>> resHashMap = new HashMap<Integer, List<Integer>>(); 33 for(int i : hs){ 34 //找到root 35 int rootParent = forest.root(i); 36 if(!resHashMap.containsKey(rootParent)){ 37 resHashMap.put(rootParent, new ArrayList<Integer>()); 38 } 39 //每个root下面的值都放在一个list里,包括root本身 40 resHashMap.get(rootParent).add(i); 41 } 42 43 for(List<Integer> item : resHashMap.values()){ 44 Collections.sort(item); 45 res.add(item); 46 } 47 return res; 48 } 49 } 50 51 class UnionFind{ 52 53 //HashMap maintaining key - > value (child -> parent) relationship 54 HashMap<Integer, Integer> parent; 55 public UnionFind(HashSet<Integer> hs){ 56 parent = new HashMap<Integer, Integer>(); 57 for(int i : hs){ 58 parent.put(i, i); 59 } 60 } 61 62 public int root(int i){ 63 while(i != parent.get(i)){ 64 parent.put(i, parent.get(parent.get(i))); 65 i = parent.get(i); 66 } 67 return i; 68 } 69 70 public void union(int i, int j){ 71 int p = root(i); 72 int q = root(j); 73 if(p != q){ 74 parent.put(p, q); 75 } 76 } 77 }