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
Example 1:
Input :list = [[1,2,3],[3,9,7],[4,5,10]]
Output:2 .
Explanation:There are 2 sets of [1,2,3,9,7] and [4,5,10] left.
Example 2:
Input:list = [[1],[1,2,3],[4],[8,7,4,5]]
Output :2
Explanation:There are 2 sets of [1,2,3] and [4,5,7,8] left.
Notice
- The number of sets
n <=1000
. - The number of elements for each set
m <= 100
. - The element must be a non negative integer and not greater than
100000
.
思路:Union Find的模板,先find最大值,然后申请union Find数组,然后用hashset统计一下点的个数,然后union一下,这里取巧,union的时候return一下true和false,这样count可以--;
public class Solution {
/**
* @param sets: Initial set list
* @return: The final number of sets
*/
private class UnionFind{
private int[] father;
private int count;
public UnionFind(int n) {
father = new int[n+1];
for(int i = 0; i <=n; i++) {
father[i] = i;
}
this.count = n;
}
public int find(int x) {
int j = x;
while(father[j] != j) {
j = father[j];
}
// path compression
while(x != j) {
int fx = father[x];
father[x] = j;
x = fx;
}
return j;
}
public boolean union(int a, int b) {
int father_a = find(a);
int father_b = find(b);
if(father_a != father_b) {
father[father_a] = father_b;
return true;
}
return false;
}
}
public int setUnion(int[][] sets) {
if(sets == null || sets.length == 0) {
return 0;
}
HashSet<Integer> hashset = new HashSet<Integer>();
int max = Integer.MIN_VALUE;
for(int i = 0; i < sets.length; i++) {
for(int j = 0; j < sets[i].length; j++) {
max = Math.max(max, sets[i][j]);
hashset.add(sets[i][j]);
}
}
UnionFind uf = new UnionFind(max);
int count = hashset.size();
for(int i = 0; i < sets.length; i++) {
for(int j = 0; j < sets[i].length-1; j++) {
if(uf.union(sets[i][j], sets[i][j+1])) {
count--;
}
}
}
return count;
}
}