zoukankan      html  css  js  c++  java
  • Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素

    381. O(1) 时间插入、删除和获取随机元素 - 允许重复

    设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构。

    注意: 允许出现重复元素。

    insert(val):向集合中插入元素 val。
    remove(val):当 val 存在时,从集合中移除一个 val。
    getRandom:从现有集合中随机获取一个元素。每个元素被返回的概率应该与其在集合中的数量呈线性相关。
    示例:

    // 初始化一个空的集合。
    RandomizedCollection collection = new RandomizedCollection();
    
    // 向集合中插入 1 。返回 true 表示集合不包含 1 。
    collection.insert(1);
    
    // 向集合中插入另一个 1 。返回 false 表示集合包含 1 。集合现在包含 [1,1] 。
    collection.insert(1);
    
    // 向集合中插入 2 ,返回 true 。集合现在包含 [1,1,2] 。
    collection.insert(2);
    
    // getRandom 应当有 2/3 的概率返回 1 ,1/3 的概率返回 2 。
    collection.getRandom();
    
    // 从集合中删除 1 ,返回 true 。集合现在包含 [1,2] 。
    collection.remove(1);
    
    // getRandom 应有相同概率返回 1 和 2 。
    collection.getRandom();
    
    //维护一个list存储所有val的值
    //维护一个map存储每个val在List的位置
    //随机只需要再list随机
    //删除操作是将所要删除的数将在list中最后一个位置的数放到所要删除的位置
    //在更新一下最有一个数在map中的位置即可
    class RandomizedCollection {
    
        private Map<Integer,Set<Integer>> map  ;
    
        private List<Integer> list ;
    
        private Random random  ;
    
        private int size = 0 ;
    
    
        public RandomizedCollection() {
            map = new HashMap<>() ;
            list = new ArrayList<>() ;
            random = new Random() ;
        }
    
        public boolean insert(int val) {
            if(map.containsKey(val)){
                Set<Integer> indexes = map.get(val) ;
                list.add(size,val) ;
                indexes.add(size) ;
                size++ ;
                return false ;
            }else{
                Set<Integer> indexes = new HashSet<>() ;
                map.put(val,indexes) ;
                list.add(size,val) ;
                indexes.add(size) ;
                size++ ;
                return true ;
            }
        }
    
        public boolean remove(int val) {
            if(!map.containsKey(val)){
                return false ;
            }
            Set<Integer> indexes = map.get(val) ;
            if(list.get(size-1) == val){
                indexes.remove(size-1) ;
                size-- ;
            }else{
                //删除下标
                Iterator<Integer> it = indexes.iterator() ;
                int index = it.next() ;
                it.remove();
                //把list的最后一个值放到对应下标那
                int last = list.get(size-1) ;
                list.set(index,last) ;
                Set<Integer> set = map.get(last) ;
                //更改我最后一个值的下标
                set.remove(size-1) ;
                set.add(index) ;
                size-- ;
            }
            if(indexes.size() == 0){
                map.remove(val) ;
            }
            return true ;
        }
    
        public int getRandom() {
            return list.get(random.nextInt(size));
        }
    }
    
    
    
    /**
     * Your RandomizedCollection object will be instantiated and called as such:
     * RandomizedCollection obj = new RandomizedCollection();
     * boolean param_1 = obj.insert(val);
     * boolean param_2 = obj.remove(val);
     * int param_3 = obj.getRandom();
     */
    
  • 相关阅读:
    JavaScript cookie详解
    Javascript数组的排序:sort()方法和reverse()方法
    javascript中write( ) 和 writeln( )的区别
    div做表格
    JS 盒模型 scrollLeft, scrollWidth, clientWidth, offsetWidth 详解
    Job for phpfpm.service failed because the control process exited with error code. See "systemctl status phpfpm.service" and "journalctl xe" for details.
    orm查询存在价格为空问题
    利用救援模式破解系统密码
    SSH服务拒绝了密码
    C# 调用 C++ DLL 中的委托,引发“对XXX::Invoke类型的已垃圾回收委托进行了回调”错误的解决办法
  • 原文地址:https://www.cnblogs.com/a1439775520/p/12946531.html
Copyright © 2011-2022 走看看