面试算法42:最近请求次数

题目

请实现如下类型RecentCounter,它是统计过去3000ms内的请求次数的计数器。该类型的构造函数RecentCounter初始化计数器,请求数初始化为0;函数ping(int t)在时间t添加一个新请求(t表示以毫秒为单位的时间),并返回过去3000ms内(时间范围为[t-3000,t])发生的所有请求数。假设每次调用函数ping的参数t都比之前调用的参数值大。

java 复制代码
public class RecentCounter {
    private Queue<Integer> times;
    private int windowsSize;
}

例如,在初始化一个RecentCounter计数器之后,ping(1)的返回值是1,因为时间范围[-2999,1]只有1个请求;ping(10)的返回值是2,因为时间范围[-2990,10]有2个请求;ping(3001)的返回值是3,因为时间范围[1,3001]有3个请求;ping(3002)的返回值是3,因为时间范围[2,3002]有3个请求,发生在时间1的请求已经不在这个时间范围内。

分析

为了解决这个问题,首先需要考虑的是用什么数据结构来记录每次请求的时间。在ping(1)、ping(10)、ping(3001)发生时,先后将时间1、10、3001记录到一个数据容器中。接下来发生了ping(3002),此时时间1已经超出当前的时间范围,时间1发生的请求不被计数,因此时间1需要从数据容器中删除。需要注意的是,在1、10、3001、3002这几个时间中,时间1是最先存入数据容器中的,它最先被删除,这符合"先入先出"的规律,因此可以考虑用队列实现这个数据容器。

java 复制代码
public class RecentCounter {
    private Queue<Integer> times;
    private int windowsSize;

    public static void main(String[] args) {
        RecentCounter recentCounter = new RecentCounter();
        System.out.println(recentCounter.ping(1));
        System.out.println(recentCounter.ping(10));
        System.out.println(recentCounter.ping(3001));
        System.out.println(recentCounter.ping(3002));
    }

    public RecentCounter() {
        times = new LinkedList<>();
        windowsSize = 3000;
    }

    public int ping(int t) {
        times.offer(t);
        while (times.peek() + windowsSize < t) {
            times.poll();
        }

        return times.size();
    }
}
相关推荐
neoooo6 分钟前
别慌,Java只有值传递——一次搞懂“为啥我改了它还不变”!
java·后端·spring
秋难降7 分钟前
Python 知识 “八股”:给有 C 和 Java 基础的你😁😁😁
java·python·c
wuxuanok9 分钟前
Web后端开发-请求响应
java·开发语言·笔记·学习
livemetee17 分钟前
spring-ai 1.0.0 (3)交互增强:Advisor 顾问模块
java
DDDDDouble22 分钟前
<二>Sping-AI alibaba 入门-记忆聊天及持久化
java·人工智能
一切顺势而行41 分钟前
kafka总结
java
Y1nhl1 小时前
力扣_链表_python版本
开发语言·python·算法·leetcode·链表·职场和发展
Codebee1 小时前
如何利用OneCode注解驱动,快速训练一个私有的AI代码助手
前端·后端·面试
一个 00 后的码农1 小时前
26考研物理复试面试常见问答问题汇总(2)电磁波高频面试问题,物理专业保研推免夏令营面试问题汇总
考研·面试·职场和发展
qq_401700411 小时前
C语言中位运算以及获取低8位和高8位、高低位合并
c语言·开发语言·算法