算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
今天和大家聊的问题叫做 敲击计数器,我们先来看题面:
https://leetcode-cn.com/problems/design-hit-counter/
Design a hit counter which counts the number of hits received in the past 5 minutes.
Each function accepts a timestamp parameter (in seconds granularity) and you may assume that calls are being made to the system in chronological order (ie, the timestamp is monotonically increasing). You may assume that the earliest timestamp starts at 1.
It is possible that several hits arrive roughly at the same time.
设计一个敲击计数器,使它可以统计在过去5分钟内被敲击次数。
每个函数会接收一个时间戳参数(以秒为单位),你可以假设最早的时间戳从1开始,且都是按照时间顺序对系统进行调用(即时间戳是单调递增)。
在同一时刻有可能会有多次敲击。
示例
HitCounter counter = new HitCounter();
// 在时刻 1 敲击一次。
counter.hit(1);
// 在时刻 2 敲击一次。
counter.hit(2);
// 在时刻 3 敲击一次。
counter.hit(3);
// 在时刻 4 统计过去 5 分钟内的敲击次数, 函数返回 3 。
counter.getHits(4);
// 在时刻 300 敲击一次。
counter.hit(300);
// 在时刻 300 统计过去 5 分钟内的敲击次数,函数返回 4 。
counter.getHits(300);
// 在时刻 301 统计过去 5 分钟内的敲击次数,函数返回 3 。
counter.getHits(301);
解题
https://blog.youkuaiyun.com/weixin_44171872/article/details/108763682
主要思路:
(1)使用队列存储敲击的时间戳,利用先进先出的特性,来再后面将需要弹出的元素过滤掉;
(2)在需要获得某个时刻的前5分钟的敲击数量时,既300秒,可以使用当前时刻减去队列头部元素时刻值,判断是否大于等于300,来过滤掉过期元素即可;
class HitCounter {
public:
queue<int> q;//存储结构
/** Initialize your data structure here. */
HitCounter() {
}
/** Record a hit.
@param timestamp - The current timestamp (in seconds granularity). */
void hit(int timestamp) {
q.push(timestamp);//存储输入的时间戳
}
/** Return the number of hits in the past 5 minutes.
@param timestamp - The current timestamp (in seconds granularity). */
int getHits(int timestamp) {
//处理过期的时间戳
while(!q.empty()&×tamp-q.front()>=300){
q.pop();
}
//返回当前有效的时间戳的数量
return q.size();
}
};
好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力 。
上期推文: