并查集
package newcoder; import java.util.HashMap; import java.util.List; import java.util.Stack; public class UnionFind { public static class Element<V> { public V value; public Element (V value) { this.value = value; } } public static class UnionFindSet<V> { /** * 根据用户的value映射为包装类 */ public HashMap<V, Element<V>> elementMap; /** * 每个element都有自己的parent,代表节点的parent为自己 */ public HashMap<Element<V>, Element<V>> parentMap; /** * 每个代表节点代表了多少节点(如果不是代表节点,则为0) */ public HashMap<Element<V>, Integer> sizeMap; /** * 初始化操作 */ public UnionFindSet(List<V> list) { elementMap = new HashMap<>(); parentMap = new HashMap<>(); sizeMap = new HashMap<>(); for (V v : list) { Element<V> ele = new Element<V>(v); elementMap.put(v, ele); parentMap.put(ele, ele); sizeMap.put(ele, 1); } } /** * 方法1:判断两个节点是否为同一个集合 */ public boolean isSameSet(V a, V b) { if(elementMap.containsKey(a) && elementMap.containsKey(b)) { return findHead(elementMap.get(a)) == findHead(elementMap.get(b)); } return false; } /** * 方法2:合并两个元素 * @param a * @param b */ public void union(V a, V b) { if(elementMap.containsKey(a) && elementMap.containsKey(b)) { Element<V> aHead = findHead(elementMap.get(a)); Element<V> bHead = findHead(elementMap.get(b)); if(aHead != bHead) { Element<V> big = sizeMap.get(aHead) > sizeMap.get(bHead) ? aHead : bHead; Element<V> small = big == aHead ? bHead : aHead; parentMap.put(small, big); sizeMap.put(big, sizeMap.get(big) + sizeMap.get(small)); sizeMap.remove(small); } } } /** * 私有方法:获取代表节点并将节点扁平化 * @param ele * @return */ private Element<V> findHead(Element<V> ele) { Stack<Element<V>> stack = new Stack<>(); while(ele != parentMap.get(ele)) { stack.push(ele); ele = parentMap.get(ele); } while(!stack.isEmpty()) { parentMap.put(stack.pop(), ele); } return ele; } } }