• 并查集的实现


    题目描述:

    给定一个没有重复值的整型数组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 }

    欢迎评论,共同进步!!

  • 相关阅读:
    rabbitmq在ios中实战采坑
    网络七层架构一句话简述
    HystrixCommand实战
    前端SEO技巧
    前端面试-难点问题2-java和javascript的区别
    前端面试题--难点问题
    [微信营销企划之路]003.Access forbidden!
    [Python进阶]001.不定参数
    [安卓基础]011存储数据(中)——sqlite语法介绍
    [JavaWeb基础] 015.Struts2 表单验证框架
  • 原文地址:https://www.cnblogs.com/hengzhezou/p/11062858.html
Copyright © 2020-2023  润新知