Brute Force: Queue

class HitCounter:
  
    def __init__(self):
        self.q = collections.deque()

    # tc O(1) sc O(N)
    def hit(self, timestamp: int) -> None:
        self.q.append(timestamp)
        
    # tc O(N) sc O(N)
    def getHits(self, timestamp: int) -> int:
        thr =  timestamp - 300 
        while self.q and self.q[0] <= thr:
            self.q.popleft()
        return len(self.q)

Notice when multiple hits at the same timestamp, we don’t want to repeated the removal opearation in the queue since it’s inefficient. we use a list with size of 2 [timestamp, counter] to record. counter is to record number of hits at timestamp t, and use a total variable to record total hits so far

class HitCounter:
  
    def __init__(self):
        self.q = collections.deque()
        self.total = 0 
    # tc O(1) sc O(N)
    def hit(self, timestamp: int) -> None:
        if not self.q or self.q[-1][0] != timestamp:
            self.q.append([timestamp,1])  # memory can go unbounded 
        else:
            self.q[-1][1] += 1
        self.total += 1 
    
    def getHits(self, timestamp: int) -> int:
        thr =  timestamp - 300 
        while self.q and self.q[0][0] <= thr:
            t,cnt = self.q.popleft()
            self.total -= cnt 
        return self.total 

Better for scale solution

class HitCounter:
class HitCounter:
    """
    if we got large stream and the expiered time is fixed, we can create two fixed arrays to store timestamp and cnt within valid time duratin (300s ) 
    """
    def __init__(self):
        self.time = [0] *300 # store timestamp 
        self.cnt  = [0] * 300 # store count at timestamp 
        self.total = 0
    # tc O(1) sc O(300)
    def hit(self, timestamp: int) -> None:
        idx = timestamp % 300
        if self.time[idx] != timestamp:
            self.time[idx] = timestamp 
            self.cnt[idx] = 1 
        else:
            self.cnt[idx] += 1
            
    # tc O(N)  sc O(300)
    def getHits(self, timestamp: int) -> int:
        res = 0
        for i in range(300):
            if timestamp - self.time[i] < 300 :
                res += self.cnt[i]
        return res