题目地址
难度:⭐
题目描述:
写一个 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) { for(int i=n-counter;i<n;++i){ if(request[i]>=t-3000 && i<=t){ break; }else{ --counter; } } request.emplace_back(t); ++counter; ++n; return counter; } };
|
💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎官 方 题 解💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎
方法一:队列
我们只会考虑最近 3000 毫秒到现在的 ping
数,因此我们可以使用队列存储这些 ping
的记录。当收到一个时间 t
的 ping
时,我们将它加入队列,并且将所有在时间 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(); } }
|
复杂度分析
⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳总 结⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳⏳
总结:
以前解题用的都是vector容器,我没有删除已经不在统计范围内的请求,这一点是我误解了,这道题确实是比较适合用队列求解,以后还是要活学活用,官方题解是用Java/Python实现的,giao,c++不香吗,学一下这个思想吧😎