java">import java.util.Arrays;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;public class UnionFind<T> {private int[] sets;private Map<T, Integer> reverseIndexMap;public UnionFind(T[] elems) {sets = new int[elems.length];Arrays.fill(sets, -1);reverseIndexMap = new HashMap<>();for (int i = 0; i < elems.length; i++) {reverseIndexMap.put(elems[i], i);}}public int find(T e) {Deque<Integer> stack = new LinkedList<>();int eIndex = reverseIndexMap.get(e);while (sets[eIndex] >= 0) {int fIndex = sets[eIndex];stack.push(eIndex);eIndex = fIndex;}while (!stack.isEmpty()) {sets[stack.pop()] = eIndex;}return eIndex;}public void union(T e1, T e2) {if (isSameSet(e1, e2)) {return;}int f1Index = find(e1);int f2Index = find(e2);int size1 = Math.abs(sets[f1Index]);int size2 = Math.abs(sets[f2Index]);if (size1 < size2) {sets[f2Index] += sets[f1Index];sets[f1Index] = f2Index;} else {sets[f1Index] += sets[f2Index];sets[f2Index] = f1Index;}}public boolean isSameSet(T e1, T e2) {return find(e1) == find(e2);}private void debug() {System.out.println(Arrays.toString(sets));}public static void main(String[] args) {String[] nums = { "1", "2", "3", "4", "5", "6" };UnionFind<String> uf = new UnionFind<>(nums);uf.union(nums[0], nums[1]);uf.union(nums[3], nums[4]);uf.debug();uf.union(nums[0], nums[4]);uf.find(nums[4]);uf.debug();}
}