933. 最近的请求次数 / 剑指 Offer II 030. 插入、删除和随机访问都是 O(1) 的容器

这篇博客介绍了两种高效的数据结构实现:一种用于记录最近的请求次数,使用List模拟,通过移动区间左端点实现O(1)的删除;另一种是O(1)时间复杂度的插入、删除和随机访问容器,利用哈希和数组实现。这两者都展示了在设计数据结构时如何优化操作效率。
摘要由CSDN通过智能技术生成

933. 最近的请求次数【简单题】【每日一题】

思路:

使用List列表进行模拟。

代码:

class RecentCounter {

    int cnt;//计数变量
    int left;//区间左端点指针
    List<Integer> list;//存储所有的请求时间

    public RecentCounter() {
        this.cnt = 0;//初始化cnt为0
        this.left = 0;//初始化left为0
        this.list = new ArrayList<>();//初始化list为空的ArrayList集合
    }
    
    public int ping(int t) {
        list.add(t);//将当前时间添加到list中
        cnt++;//计数变量+1
        //当前这个t如果与left指针指向的t相距大于3000ms,说明left指针指向的t计数失效,需要减掉
        while(t-3000 > list.get(left)){
            left++;//右移left指针继续判断
            cnt--;//cnt减去失效的1
        }
        return cnt; //返回cnt
    }
}

/**
 * Your RecentCounter object will be instantiated and called as such:
 * RecentCounter obj = new RecentCounter();
 * int param_1 = obj.ping(t);
 */

剑指 Offer II 030. 插入、删除和随机访问都是 O(1) 的容器【中等题】

思路:

通过哈希来实现插入和删除,通过int[] 数组实现数据结构,通过数组下标来实现随机访问。
这道题与主站第380题相同。
380. O(1)时间插入、删除和获取随机元素

代码:

class RandomizedSet {

    int[] nums; //要存储的数据结构
    Map<Integer,Integer> map;//用来判断元素在插入或删除时是否存在
    Random random;//随机数生成器
    int index;//nums中待操作的下标

    /** Initialize your data structure here. */
    public RandomizedSet() {
        //初始化nums,map,random,index
        this.nums = new int[200000];
        this.map = new HashMap<>();
        this.random = new Random();
        this.index = 0;
    }
    
    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    public boolean insert(int val) {
        //如果已经存在,则插入失败,返回false
        if(map.containsKey(val)){
            return false;
        }
        //将val作为key添加到map中,index为其value
        map.put(val,index);
        //将nums数组的index位置更新为val,并使index++
        nums[index++] = val;
        //返回true
        return true;
    }
    
    /** Removes a value from the set. Returns true if the set contained the specified element. */
    public boolean remove(int val) {
        //如果不存在,则删除失败,返回false
        if(!map.containsKey(val)){
            return false;
        }
        //将val元素删除,并获取其value,也就是其在nums中对应的下标
        int del = map.remove(val);
        //判断其是否是nums中最右侧的有效下标
        if(del != index-1){
            //如果不是,说明删掉的是nums中间的某个元素,那么此时需要在map中将此时nums最右侧那个有效的元素对应的nums下标更新为刚刚删除的那个下标
            map.put(nums[index-1],del);
        }
        //如果del就是nums中最右侧的有效下标,或者本来不是,但是经过上述操作之后最右侧的元素对应的下标已经补到刚删掉的位置(此时nums最右侧有效位置已经失效)
        //将最右侧有效位置的数字挪到刚刚删掉的位置del
        nums[del] = nums[index-1];
        //待处理下标左移1位
        index--;
        //删除成功返回true
        return true;
    }
    
    /** Get a random element from the set. */
    public int getRandom() {
        int i = random.nextInt(index);
        return nums[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();
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值