原题
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.
Example:
HitCounter counter = new HitCounter();
// hit at timestamp 1.
counter.hit(1);
// hit at timestamp 2.
counter.hit(2);
// hit at timestamp 3.
counter.hit(3);
// get hits at timestamp 4, should return 3.
counter.getHits(4);
// hit at timestamp 300.
counter.hit(300);
// get hits at timestamp 300, should return 4.
counter.getHits(300);
// get hits at timestamp 301, should return 3.
counter.getHits(301);
Follow up:
What if the number of hits per second could be very large? Does your design scale?
解法1
构建列表, 每次hit时, 往列表里加timestamp, 每次getHits时, 检查目前的timeStamp与列表的第一个元素的间隔是否>= 300, 如果是, 那么一直从列表头部删除元素直到timeStamp与列表的第一个元素的间隔 < 300为止, 然后返回self.data的长度即可.
代码
class HitCounter:
def __init__(self):
"""
Initialize your data structure here.
"""
self.data = []
def hit(self, timestamp: 'int') -> 'None':
"""
Record a hit.
@param timestamp - The current timestamp (in seconds granularity).
"""
self.data.append(timestamp)
def getHits(self, timestamp: 'int') -> 'int':
"""
Return the number of hits in the past 5 minutes.
@param timestamp - The current timestamp (in seconds granularity).
"""
while self.data and timestamp - self.data[0] >= 300:
self.data.pop(0)
return len(self.data)
解法2
同解法1, 但使用双向队列.
代码
class HitCounter:
def __init__(self):
"""
Initialize your data structure here.
"""
self.data = collections.deque()
def hit(self, timestamp: int) -> None:
"""
Record a hit.
@param timestamp - The current timestamp (in seconds granularity).
"""
self.data.append(timestamp)
def getHits(self, timestamp: int) -> int:
"""
Return the number of hits in the past 5 minutes.
@param timestamp - The current timestamp (in seconds granularity).
"""
while self.data and timestamp - self.data[0] >= 300:
self.data.popleft()
return len(self.data)
解法3
字典, 使用字典存储时间点和计数, 在getHits函数里, 查找离timestamp在300秒之内的key, 然后将值累加即可.
代码
class HitCounter:
def __init__(self):
"""
Initialize your data structure here.
"""
self.dict = collections.defaultdict(int)
def hit(self, timestamp: int) -> None:
"""
Record a hit.
@param timestamp - The current timestamp (in seconds granularity).
"""
self.dict[timestamp] = self.dict.get(timestamp, 0) + 1
def getHits(self, timestamp: int) -> int:
"""
Return the number of hits in the past 5 minutes.
@param timestamp - The current timestamp (in seconds granularity).
"""
ans = [self.dict[timestamp-i] for i in range(300)]
return sum(ans)