Partitioning connected component
2018-02-23 本文已影响0人
Star_C
Question: Given a graph where nodes have directed neighbours. Partition them into connected groups.
E.g.
IN: 1 to 2, 1 to 3, 2 to 3, 4 to 5
OUT: 1,2,3 and 4,5
Idea:
- solution : use Union Find to put them into groups, and then output them
Code for solution 1:
class DirectedGraphNode {
int label;
ArrayList<DirectedGraphNode> neighbors;
DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); }
}
class UnionFind<T> {
private Map<T, T> m_rootMap = null;
private long m_groupCount = 0;
private void addWithoutCheck(T x) {
m_rootMap.put(x, x);
m_groupCount++;
}
private void add(T x) {
if (!m_rootMap.containsKey(x)) {
addWithoutCheck(x);
}
}
public UnionFind() {
m_rootMap = new HashMap<T, T>();
m_groupCount = 0;
}
public T find(T x) {
add(x);
T root = m_rootMap.get(x);
if (root.equals(x)) {
return x;
} else {
m_rootMap.put(x, find(root));
}
return m_rootMap.get(x);
}
public void connect(T a, T b) {
T root_a = find(a);
T root_b = find(b);
if (!root_a.equals(root_b)) {
m_rootMap.put(root_b, root_a);
m_groupCount--;
}
}
static final boolean debug = false;
static void p(Object any) {
if(debug)
System.out.println(any);
}
}
public class Solution {
/*
* @param nodes: a array of Directed graph node
* @return: a connected set of a directed graph
*/
public List<List<Integer>> connectedSet2(ArrayList<DirectedGraphNode> nodes) {
UnionFind<Integer> uf = new UnionFind<>();
for(DirectedGraphNode n : nodes) {
for(DirectedGraphNode nei: n.neighbors) {
uf.connect(n.label, nei.label);
}
}
Map<Integer, Set<Integer>> groups = new HashMap<>();
for(DirectedGraphNode n : nodes) {
Integer root = uf.find(n.label);
if (!groups.containsKey(root))
groups.put(root, new HashSet<>());
Set<Integer> bag = groups.get(root);
bag.add(n.label);
}
List<List<Integer>> list = new LinkedList<>();
for(Set<Integer> bag : groups.values()) {
List<Integer> l = new LinkedList<>();
l.addAll(bag);
list.add(l);
}
return list;
}
}
Test Case:
will be added later...