持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
写一个 RecentCounter 类来计算特定时间范围内最近的请求。
请你实现 RecentCounter 类:
RecentCounter(): 初始化计数器,请求数为 0 。int ping(int t): 在时间t添加一个新请求,其中t表示以毫秒为单位的某个时间,并返回过去 3000 毫秒内发生的所有请求数(包括新请求)。确切地说,返回在[t-3000, t]内发生的请求数。
保证 每次对 ping 的调用都使用比之前更大的 t 值。
示例
输入:
["RecentCounter", "ping", "ping", "ping", "ping"]
[[], [1], [100], [3001], [3002]]
输出:
[null, 1, 2, 3, 3]
第一行是调用函数名,第二行是函数的参数:
- 调用
RecentCounter,初始化计数器,返回空 - 调用
ping,参数是 1,即查询窗口在[-2999, 1]之间有多少ping。当前请求数组:[1],返回 1 - 调用
ping,参数是 100,即查询窗口在[-2900, 100]之间有多少ping。当前请求数组:[1, 100],返回 2 - 调用
ping,参数是 3001,即查询窗口在[1, 3001]之间有多少ping。当前请求数组:[1, 100, 3001],返回 3 - 调用
ping,参数是 3002,即查询窗口在[2, 3002]之间有多少ping。当前请求数组:[1, 100, 3001, 3002],返回 3
思路
需要注意的点:
- 返回过去 3000 毫秒内的请求数
[t-3000, t],是一个左闭右闭的区间 - 每次的
ping是严格递增的
方法1:队列
我们可以用一个队列来维护发生请求的时间,当在时间 t 收到请求时,将时间 t 入队、
由于每次收到的请求的时间都比之前的大,因此队首到队尾的时间是单调递增的。
var RecentCounter = function() {
this.queue = []
}
RecentCounter.prototype.ping = function(t) {
this.queue.push(t)
while(this.queue[0] < t - 3000) {
this.queue.shift()
}
return this.queue.length
}
方法2:快慢指针
- 定义一个数组和快慢指针:
arr,slow和fast - 每次调用
ping函数(请求时间t进入数组),都让fast指向当前t - 然后对
slow进行while判断,使其前进到小于t - 3000的位置 - 最后返回快慢指针位置的差值即可
var RecentCounter = function() {
this.arr = []
this.fast = 0
this.slow = 0
}
RecentCounter.prototype.ping = function(t) {
this.arr[this.fast++] = t
while(this.arr[this.slow] < t - 3000) this.slow++
// 返回数组的大小 = 发生的请求数
return this.fast - this.slow
}
\