介绍并查集文章 https://blog.csdn.net/zjy_code/article/details/80634149

    image.png

    1. public class UnionFind {
    2. public static class Element<V> {
    3. public V value;
    4. public Element(V value) {
    5. this.value = value;
    6. }
    7. }
    8. public static class UnionFindSet<V> {
    9. public HashMap<V, Element<V>> elementMap;
    10. // key 某个元素 value 该元素的父
    11. public HashMap<Element<V>, Element<V>> fatherMap;
    12. // key 某个集合的代表元素 value 该集合的大小
    13. public HashMap<Element<V>, Integer> rankMap;
    14. public UnionFindSet(List<V> list) {
    15. elementMap = new HashMap<>();
    16. fatherMap = new HashMap<>();
    17. rankMap = new HashMap<>();
    18. for (V value : list) {
    19. Element<V> element = new Element<V>(value);
    20. elementMap.put(value, element);
    21. fatherMap.put(element, element);
    22. rankMap.put(element, 1);
    23. }
    24. }
    25. private Element<V> findHead(Element<V> element) {
    26. Stack<Element<V>> path = new Stack<>();
    27. while (element != fatherMap.get(element)) {
    28. path.push(element);
    29. element = fatherMap.get(element);
    30. }
    31. while (!path.isEmpty()) {
    32. fatherMap.put(path.pop(), element);
    33. }
    34. return element;
    35. }
    36. public boolean isSameSet(V a, V b) {
    37. if (elementMap.containsKey(a) && elementMap.containsKey(b)) {
    38. return findHead(elementMap.get(a)) == findHead(elementMap.get(b));
    39. }
    40. return false;
    41. }
    42. public void union(V a, V b) {
    43. if (elementMap.containsKey(a) && elementMap.containsKey(b)) {
    44. Element<V> aF = findHead(elementMap.get(a));
    45. Element<V> bF = findHead(elementMap.get(b));
    46. if (aF != bF) {
    47. Element<V> big = rankMap.get(aF) >= rankMap.get(bF) ? aF : bF;
    48. Element<V> small = big == aF ? bF : aF;
    49. fatherMap.put(small, big);
    50. rankMap.put(big, rankMap.get(aF) + rankMap.get(bF));
    51. rankMap.remove(small);
    52. }
    53. }
    54. }
    55. }
    56. }