• 并查集的实现


    题目描述:

    给定一个没有重复值的整型数组arr,初始时认为arr中每一个数各自都是一个单独的集合,请设计一种叫UnionFind的结构,并提供以下两个操作。

    (1)boolean isSameSet(int a,int b):查询a和b这两个数是否属于一个集合。

    (2)void union(int a,int b):把a所在的集合与b所在的集合合并在一起,原本两个集合各自的元素以后都算作同一个集合。

    要求:

    如果调用isSameSet和union的总次数逼近或超过O(N),请做到单词调用isSameSet或union方法的平均时间复杂度为O(1)。

    解答:

    符合题目功能要求的结构就是并查集。

     1 class Element<V> {
     2     public V value;
     3     public Element(V value) {
     4         this.value=value;
     5     }
     6 }
     7 public class UnionFindSet<V> {
     8     public HashMap<V,Element<V>> elementMap;
     9     public HashMap<Element<V>,Element<V>> fatherMap;
    10     public HashMap<Element<V>,Integer> rankMap;
    11 
    12     public UnionFindSet(List<V> list) {
    13         elementMap=new HashMap<>();
    14         fatherMap =new HashMap<>();
    15         rankMap=new HashMap<>();
    16         for (V value : list) {
    17             Element<V> element=new Element<V>(value);
    18             elementMap.put(value,element);
    19             fatherMap.put(element,element);
    20             rankMap.put(element,1);
    21             
    22         }
    23     }
    24     private Element<V> findHead(Element<V> element) {
    25         Stack<Element<V>> path=new Stack<>();
    26         while(element!=fatherMap.get(element)) {
    27             path.push(element);
    28             element=fatherMap.get(element);
    29         }
    30         while (!path.isEmpty()) {
    31             fatherMap.put(path.pop(),element);
    32         }
    33         return element;
    34     }
    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 }

    欢迎评论,共同进步!!

  • 相关阅读:
    MySQL数据丢失讨论
    分布式系统之Quorum (NRW)算法
    阿里巴巴-OS事业群-OS手机事业部-系统服务部门招聘Java开发工程师,有意者请进来
    EQueue
    ENode 2.0
    关于MySQL的在线扩容
    我收藏的技术知识图(每张都是大图)
    关于实现一个基于文件持久化的EventStore的核心构思
    Actor的原理
    OAuth 2.0 授权原理
  • 原文地址:https://www.cnblogs.com/hengzhezou/p/11062858.html
Copyright © 2020-2023  润新知