0%

最近的请求次数

题目地址

难度:

题目描述:

写一个 RecentCounter 类来计算特定时间范围内最近的请求。

请你实现 RecentCounter 类:

RecentCounter() 初始化计数器,请求数为 0 。
int ping(int t) 在时间 t 添加一个新请求,其中 t 表示以毫秒为单位的某个时间,并返回过去 3000 毫秒内发生的所有请求数(包括新请求)。确切地说,返回在 [t-3000, t] 内发生的请求数。
保证 每次对 ping 的调用都使用比之前更大的 t 值。

示例1:

1
2
3
4
5
6
7
8
9
10
11
12
输入:
["RecentCounter", "ping", "ping", "ping", "ping"]
[[], [1], [100], [3001], [3002]]
输出:
[null, 1, 2, 3, 3]

解释:
RecentCounter recentCounter = new RecentCounter();
recentCounter.ping(1); // requests = [1],范围是 [-2999,1],返回 1
recentCounter.ping(100); // requests = [1, 100],范围是 [-2900,100],返回 2
recentCounter.ping(3001); // requests = [1, 100, 3001],范围是 [1,3001],返回 3
recentCounter.ping(3002); // requests = [1, 100, 3001, 3002],范围是 [2,3002],返回 3

提示:

  • 1 <= t <= 10^9
  • 保证每次对 ping 调用所使用的 t 值都 严格递增
  • 至多调用 ping 方法 10^4
🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️解题过程🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️🙋‍♂️
解题过程:

思路:

初始化计数器为0,定义一个vector容器存储请求,然后调用ping()时在存储请求容器中添加一个新请求,计数器加1,遍历上次请求范围内的请求,判断它们是否满足在当前请求的范围中,若不满足则计数器减一,最后返回计数器.

c++代码:(执行用时240ms,击败97.33%,内存消耗57.3M,击败6.80%)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class RecentCounter {
public:
vector<int> request;
int counter;
//请求总数
int n;
RecentCounter() {
counter=0;
n=0;
}
int ping(int t) {
//加上当前请求数,所以初始值为1
//int n=request.size();
//遍历距上次请求3000ms范围内的请求,从前向后依此判断是否在当前请求范围内
for(int i=n-counter;i<n;++i){
if(request[i]>=t-3000 && i<=t){
//还满足时间范围,则以后的都满足
break;
}else{
//不满足则最近请求计数减1,继续遍历
--counter;
}
}
//添加新请求
request.emplace_back(t);
++counter;
++n;
return counter;
}
};

/**
* Your RecentCounter object will be instantiated and called as such:
* RecentCounter* obj = new RecentCounter();
* int param_1 = obj->ping(t);
*/
💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎官 方 题 解💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎
官方题解:

方法一:队列
我们只会考虑最近 3000 毫秒到现在的 ping 数,因此我们可以使用队列存储这些 ping 的记录。当收到一个时间 tping 时,我们将它加入队列,并且将所有在时间 t - 3000 之前的 ping 移出队列。

Java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
class RecentCounter {
Queue<Integer> q;
public RecentCounter() {
q = new LinkedList();
}

public int ping(int t) {
q.add(t);
while (q.peek() < t - 3000)
q.poll();
return q.size();
}
}

复杂度分析

  • 时间复杂度:$O(Q)$,其中 $Q$ 是 ping 的次数。

  • 空间复杂度:$O(W)$,其中 $W = 3000$ 是队列中最多存储的 ping 的记录数目。

⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳总 结⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳
总结:

以前解题用的都是vector容器,我没有删除已经不在统计范围内的请求,这一点是我误解了,这道题确实是比较适合用队列求解,以后还是要活学活用,官方题解是用Java/Python实现的,giao,c++不香吗,学一下这个思想吧😎

------------- THE END! THANKS! -------------