Insert Delete GetRandom O(1) - Duplicates allowed in JAVA

题目描述:
Design a data structure that supports all following operations in average O(1) time.

Note: Duplicate elements are allowed.
insert(val): Inserts an item val to the collection.
remove(val): Removes an item val from the collection if present.
getRandom: Returns a random element from current collection of elements. The probability of each element being returned is linearly related to the number of same value the collection contains.
Example:

// Init an empty collection.
RandomizedCollection collection = new RandomizedCollection();

// Inserts 1 to the collection. Returns true as the collection did not contain 1.
collection.insert(1);

// Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1].
collection.insert(1);

// Inserts 2 to the collection, returns true. Collection now contains [1,1,2].
collection.insert(2);

// getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3.
collection.getRandom();

// Removes 1 from the collection, returns true. Collection now contains [1,2].
collection.remove(1);

// getRandom should return 1 and 2 both equally likely.
collection.getRandom();

简单说就是构造一个数据结构,能够插入,删除以及getrandom。允许重复的值,但都是integer。

难处就在于有O(1)复杂度的限制,因此用HashMap/HashSet.
note: hashMap 的平均复杂度是O(1),记住就好

所以解题思路大致是:一个HashMap(Integer, HashSet(Integer)) h1用来保存 value

一个HashMap(Integer, HashSet(Integer)) h1用来保存 value以及其对应的key值的set,再用另一 HashMap(Integer,Integer) h2来保存key值与value的mapping关系。

insert的想法很简单,插入一个的时候就在h1 中value对应的set中添加key值, h2中直接一个一个添加key-value对。

remove的想法是:h1中从val对应的key set中任意选一个key删除, h2中将此key对应的value与h2末尾的value调换,并对应更新h1,删除h2末尾,删除h1相应的set中的key。
我觉得h2这么做的原因是为了getrandom时候可以直接random*h2.size()得到randomly,减少复杂度

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

public class RandomizedCollection {
    HashMap<Integer,Integer> h2;
    HashMap<Integer,HashSet<Integer>>h1;


     public RandomizedCollection() {
            h1=new HashMap<Integer,HashSet<Integer>>();
            h2=new HashMap<Integer,Integer>();

        }

        /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
        public boolean insert(int val) {

            boolean contain=true;
//          System.out.println(h1.size()+",,,"+h2.size());
            if(h1.containsKey(val)){
                HashSet s=h1.get(val);
                s.add(h2.size());

                contain=false;}
            else{ contain=true;
            HashSet s=new HashSet();
            s.add(h2.size());
            h1.put(val, s);
            }

            h2.put(h2.size(), val);

            return contain;
        }

        /** Removes a value from the collection. Returns true if the collection contained the specified element. */
        public boolean remove(int val) {

            boolean contain=false;

            if(h1.containsKey(val)){

                contain=true;
        Iterator<Integer>   keyIter=h1.get(val).iterator();
        int key=keyIter.next();

//      System.out.println("start Val:"+val);

        HashSet<Integer>s=h1.get(val);
//      System.out.println("start h2(key)"+h2.get(key));


       if (s.size()-1==0){

//         560503203817

//         System.out.println("val:"+val);

           int lastVal=h2.get(h2.size()-1);
//         System.out.println("lastVal:"+lastVal);
//         System.out.println(val!=lastVal);
          if(val!=lastVal){




             HashSet<Integer> s2=h1.get(lastVal);
             s2.remove(h2.size()-1);
             s2.add(key);
           h2.put(key, lastVal);}
          h1.remove(val);

           h2.remove(h2.size()-1);

           }

       else {

           if(key==h2.size()-1){
               s.remove(key);
//           
          h2.remove(h2.size()-1);}
      else{
          int lastVal=h2.get(h2.size()-1);
          if(val==lastVal){
              s.remove(h2.size()-1);
              h2.remove(h2.size()-1);
          }
          else{
              s.remove(key);
          HashSet<Integer>s2=h1.get(lastVal);
          s2.add(key);
          s2.remove(h2.size()-1);
        h2.put(key, lastVal);
          h2.remove(h2.size()-1);}
      }}

            }

            return contain;
        }

        /** Get a random element from the collection. */
        public int getRandom() {
            if (h2.size()==0)return 0;
            int rand=(int)(Math.random()*(h2.size()));
       //   System.out.println(rand);
            return h2.get(rand);
        }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值