Number of Components

Number of Connected Components in an Undirected Graph, 维护一个numOfComponents的变量。在完成每一组edge的union以后,return这个numOfComponents。

public class Solution {
    public int countComponents(int n, int[][] edges) {
        if (n <= 1) {
            return n;
        }

        UnionFind uf = new UnionFind(n);
        for (int[] e: edges) {
            int u = e[0];
            int v = e[1];
            uf.union(u, v);
        }

        return uf.getNumOfComponents();
    }
}

class UnionFind {
    private Map<Integer, Integer> parent = new HashMap<Integer, Integer>();
    private Map<Integer, Integer> size = new HashMap<Integer, Integer>();
    private int numOfComponents;

    public UnionFind(int n) {
        for (int i = 0; i < n; i++) {
            parent.put(i, i);
            size.put(i, 1);
        }
        numOfComponents = n;
    }

    public int find(int x) {
        int father = parent.get(x);
        while (father != parent.get(father)) {
            father = parent.get(father);
        }

        while (parent.get(x) != father) {
            int next = parent.get(x);
            parent.put(x, father);
            x = next;
        }

        return father;
    }

    public void union(int x, int y) {
        int x_father = find(x);
        int y_father = find(y);

        if (x_father != y_father) {
            int x_size = size.get(x_father);
            int y_size = size.get(y_father);
            if (x_size > y_size) {
                parent.put(y_father, x_father);
                size.put(x_father, x_size + y_size);
            } else {
                parent.put(x_father, y_father);
                size.put(y_father, x_size + y_size);
            }
            numOfComponents--;
        }
    }

    public int getNumOfComponents() {
        return numOfComponents;
    }
}

Find the Weak Connected Component in the Directed Graph, 把所有的node与neighbors都union了以后,遍历uf的parent map, 得到每一组group。

/**
 * Definition for Directed graph.
 * class DirectedGraphNode {
 *     int label;
 *     ArrayList<DirectedGraphNode> neighbors;
 *     DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); }
 * };
 */
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) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if (nodes == null || nodes.size() == 0) {
            return result;
        }

        Set<DirectedGraphNode> set = new HashSet<DirectedGraphNode>(nodes);
        UnionFind uf = new UnionFind(set);

        for (DirectedGraphNode node: nodes) {
            for (DirectedGraphNode neighbor: node.neighbors) {
                uf.union(node.label, neighbor.label);
            }
        }

        Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
        for (int key: uf.parent.keySet()) {
            int parent = uf.find(key);
            if (!map.containsKey(parent)) {
                map.put(parent, new ArrayList<Integer>());
            }
            map.get(parent).add(key);
        }

        for (List<Integer> list: map.values()) {
            Collections.sort(list);
            result.add(list);
        }
        return result;
    }
}

class UnionFind {
    Map<Integer, Integer> parent = new HashMap<Integer, Integer>();
    Map<Integer, Integer> size = new HashMap<Integer, Integer>();

    public UnionFind(Set<DirectedGraphNode> set) {
        for (DirectedGraphNode node: set) {
            parent.put(node.label, node.label);
            size.put(node.label, 1);
        }
    }

    public int find(int x) {
        int father = parent.get(x);
        while (father != parent.get(father)) {
            father = parent.get(father);
        }

        while (parent.get(x) != father) {
            int next = parent.get(x);
            parent.put(x, father);
            x = next;
        }

        return father;
    }

    public void union(int x, int y) {
        int x_father = find(x);
        int y_father = find(y);

        if (x_father != y_father) {
            int x_size = size.get(x_father);
            int y_size = size.get(y_father);

            if (x_size > y_size) {
                parent.put(y_father, x_father);
                size.put(x_father, x_size + y_size);
            } else {
                parent.put(x_father, y_father);
                size.put(y_father, x_size + y_size);
            }
        }
    }
}

results matching ""

    No results matching ""