leetcode Insert Delete GetRandom O(1) 插入删除随机数 java

题干

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

insert(val):当元素 val 不存在时,向集合中插入该项。
remove(val):元素 val 存在时,从集合中移除该项。
getRandom:随机返回现有集合中的一项。每个元素应该有相同的概率被返回。
示例 :

// 初始化一个空的集合。
RandomizedSet randomSet = new RandomizedSet();

// 向集合中插入 1 。返回 true 表示 1 被成功地插入。
randomSet.insert(1);

// 返回 false ,表示集合中不存在 2 。
randomSet.remove(2);

// 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。
randomSet.insert(2);

// getRandom 应随机返回 1 或 2 。
randomSet.getRandom();

// 从集合中移除 1 ,返回 true 。集合现在包含 [2] 。
randomSet.remove(1);

// 2 已在集合中,所以返回 false 。
randomSet.insert(2);

// 由于 2 是集合中唯一的数字,getRandom 总是返回 2 。
randomSet.getRandom();

分析

这道题就是想让我们设计一个数据结构,
要求能够以 **O(1)**查找,存储数据。
其实就会反映出来,这分别是链表和数组的特点。
好其实就该轮到哈希表了,关于哈希表都应该比较熟悉,相关数据结构的知识可以参考:
https://blog.csdn.net/woshimaxiao1/article/details/83661464
这位大佬写的很清楚了。
这里我们来复习一下Java的hashmap的常用函数操作:
在这里插入图片描述
$ hashmap.put(a,b):存放键值

$ hashmap.get(a)// 通过键对象查找得到值对象

$ hashmap .size()//大小

$ hashmap.isEmpty();

$ hashmap.containsKey(a)//是否含有键对象

$ hashmap.containsValue//是否含有值对象

说一下编码思路

一个List 来存储这些要存的数,每存一个数都存在List的末尾
一个HashMap来存储这些数和它对应的位置

插入:
先去HashMap查找是否有这个值,已经有就返回false;
如果没有,插入到list的末尾,在HashMap存储对应位置

删除
如果HashMap里没有这个数,返回false;
如果有这个数,先去HashMap查找对应的位置,
将list的最后一个数和要删除的这个数调换位置,然后删掉最后一个数。
这么做是因为:要求0(1),不能遍历,那就都删最后一个位置。把原来最后位置的那个数取出来,和要删除的数更换位置就行。

随机get
使用random的nextInt

java代码

class RandomizedSet {
        List<Integer> sub;
        HashMap<Integer,Integer> hm;
        Random rand;
    /** Initialize your data structure here. */
    public RandomizedSet() {
      
        
        sub =new ArrayList<Integer>();
        hm=new HashMap<Integer,Integer>();
        rand =new Random();
        
    }
    
    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    public boolean insert(int val) {
        if(hm.containsKey(val)){
            return false;
        }
        else{
            sub.add(val);
            hm.put(val,sub.size()-1);
            return true;
        }
      
        
        
    }
    
    /** Removes a value from the set. Returns true if the set contained the specified element. */
    public boolean remove(int val) {
        if(!hm.containsKey(val)){
            return false;
        }
        else{//换位置,再删
            int val_index=hm.get(val);
            if(val_index<sub.size()-1){
                int lastElement=sub.get(sub.size()-1);
                sub.set(val_index,lastElement);
                hm.put(lastElement,val_index);
            }
            hm.remove(val);
            sub.remove(sub.size()-1);
            return true;
        }
        
    }
    
    /** Get a random element from the set. */
    public int getRandom() {
         return sub.get(rand.nextInt(sub.size()));
    }
}

/**
 * Your RandomizedSet object will be instantiated and called as such:
 * RandomizedSet obj = new RandomizedSet();
 * boolean param_1 = obj.insert(val);
 * boolean param_2 = obj.remove(val);
 * int param_3 = obj.getRandom();
 */

速度很快,战胜99%+;

大佬代码:

class RandomizedSet {
    Map<Integer,Integer> map;
    List<Integer> list;
    /** Initialize your data structure here. */
    public RandomizedSet() {
        map = new HashMap<Integer,Integer>();
        list = new ArrayList<Integer>();
    }
    
    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    public boolean insert(int val) {
        if(!map.containsKey(val)){
            map.put(val,list.size());
            list.add(val);
            return true;
        }
        return false;
    }
    
    /** Removes a value from the set. Returns true if the set contained the specified element. */
    public boolean remove(int val) {
        if(map.containsKey(val)){
            int index = map.remove(val);
            list.set(index,Integer.MIN_VALUE);
            return true;
        }
        return false;
    }
    
    /** Get a random element from the set. */
    public int getRandom() {
        Random rm = new Random();
        int i = rm.nextInt(list.size());
        while(list.get(i) == Integer.MIN_VALUE){
            i = rm.nextInt(list.size());
        }
        
        return list.get(i);
    }
}

/**
 * Your RandomizedSet object will be instantiated and called as such:
 * RandomizedSet obj = new RandomizedSet();
 * boolean param_1 = obj.insert(val);
 * boolean param_2 = obj.remove(val);
 * int param_3 = obj.getRandom();
 */

总结

这道题很好玩
这道题是考察对已经掌握的数据结构的特点的掌握程度。
如果所有数据结构都重新定义(当然也可以)工程量十分巨大,建立在已有数据结构上定义一种新的其实就ok
(哈希表本身也是这样封装的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值