Problem

There is a list composed by sets. If two sets have the same elements, merge them. In the end, there are several sets left.

Example

Given list = [[1,2,3],[3,9,7],[4,5,10]], return 2.

Explanation:
There are 2 sets of [1,2,3,9,7] and [4,5,10] left.
Given list = [[1],[1,2,3],[4],[8,7,4,5]], return 2.

Explanation:
There are 2 sets of [1,2,3] and [4,5,7,8] left.

Solution

public class Solution {
    /**
     * @param sets: Initial set list
     * @return: The final number of sets
     */
    public int setUnion(int[][] sets) {
        int groupNum = sets.length;
        int itemNum = 40000;
        //parent's length would be the number of groups. 
        //unsure about the number of items, so use 40000 
        int[] parent = new int[groupNum];
        int[] index = new int[itemNum];
    
        for (int i = 0; i < groupNum; i++) {
            parent[i] = i;
        }
        //assign a never-used-in-index value
        Arrays.fill(index, -1);
    
        for (int i = 0; i < sets.length; i++) {
            for (int j : sets[i]) {
                //merge j's parent with i's parent first, then update j's parent
                if (index[j] != -1 && index[j] != i) {
                    merge(parent, i, index[j]);
                }
                index[j] = find(parent, i);
            }
        }
        
        int res = 0;
        for (int i = 0; i < sets.length; i++) {
            if (parent[i] == i) {
                res++;
            }
        }
        return res;
    }
    
    private int find(int[] parent, int a) {
        if (parent[a] == a) {
            return a;
        }
        parent[a] = find(parent, parent[a]);
        return parent[a];
    }
    
    private void merge(int[] parent, int a, int b) {
        int fa = find(parent, a);
        int fb = find(parent, b);
        parent[fa] = fb;
    }
}

linspiration
161 声望53 粉丝