The "Tweet Counts Per Frequency" problem asks you to design a system that can:
The system should implement three main methods:
recordTweet(tweetName, time)
: Records that a tweet with name tweetName
occurred at time
seconds.getTweetCountsPerFrequency(freq, tweetName, startTime, endTime)
: Returns a list of counts of tweets with name tweetName
for each interval of length specified by freq
("minute", "hour", "day") between startTime
and endTime
(inclusive).Key Constraints:
startTime
and endTime
, even if the count is zero.The first step is to recognize that we need to efficiently store and retrieve tweet times for each tweet name. For each query, we need to quickly count how many tweets fall into each interval of the requested frequency.
A brute-force approach would be to scan through all recorded tweet times for every query and manually count which times fall into each interval. However, this would be very slow if there are many tweets or queries.
To optimize, we can:
startTime
and endTime
.Here's how we can implement the solution step by step:
((endTime - startTime) // interval) + 1
We use binary search (e.g., the bisect
module in Python) because it allows us to efficiently find the start and end indices of tweet times within a range, making the count operation O(log n) per interval.
Suppose we perform the following operations:
recordTweet("tweet1", 10)
recordTweet("tweet1", 20)
recordTweet("tweet1", 120)
getTweetCountsPerFrequency("minute", "tweet1", 0, 119)
[2, 0]
.
Brute-force Approach:
The optimized approach is much faster, especially when there are many tweets or queries.
In this problem, we designed a system to efficiently record tweet times and answer frequency-based queries. By storing tweet times in sorted lists and using binary search, we can quickly answer queries about how many tweets occurred in each interval of a given frequency. This approach balances fast insertions and efficient queries, making it suitable for large-scale use cases.
from bisect import bisect_left, bisect_right
from collections import defaultdict
class TweetCounts:
def __init__(self):
self.tweets = defaultdict(list)
def recordTweet(self, tweetName: str, time: int) -> None:
self.tweets[tweetName].append(time)
def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int):
interval = {"minute": 60, "hour": 3600, "day": 86400}[freq]
times = self.tweets[tweetName]
times.sort()
n_intervals = ((endTime - startTime) // interval) + 1
res = [0] * n_intervals
for t in times:
if startTime <= t <= endTime:
idx = (t - startTime) // interval
res[idx] += 1
return res
#include <vector>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
class TweetCounts {
map<string, vector<int>> tweets;
public:
TweetCounts() {}
void recordTweet(string tweetName, int time) {
tweets[tweetName].push_back(time);
}
vector<int> getTweetCountsPerFrequency(string freq, string tweetName, int startTime, int endTime) {
int interval = freq == "minute" ? 60 : (freq == "hour" ? 3600 : 86400);
vector<int>& times = tweets[tweetName];
sort(times.begin(), times.end());
int n_intervals = (endTime - startTime) / interval + 1;
vector<int> res(n_intervals, 0);
for (int t : times) {
if (t >= startTime && t <= endTime) {
int idx = (t - startTime) / interval;
res[idx]++;
}
}
return res;
}
};
import java.util.*;
class TweetCounts {
Map<String, List<Integer>> tweets;
public TweetCounts() {
tweets = new HashMap<>();
}
public void recordTweet(String tweetName, int time) {
tweets.computeIfAbsent(tweetName, k -> new ArrayList<>()).add(time);
}
public List<Integer> getTweetCountsPerFrequency(String freq, String tweetName, int startTime, int endTime) {
int interval = 0;
if (freq.equals("minute")) interval = 60;
else if (freq.equals("hour")) interval = 3600;
else if (freq.equals("day")) interval = 86400;
List<Integer> times = tweets.getOrDefault(tweetName, new ArrayList<>());
Collections.sort(times);
int n_intervals = (endTime - startTime) / interval + 1;
List<Integer> res = new ArrayList<>(Collections.nCopies(n_intervals, 0));
for (int t : times) {
if (t >= startTime && t <= endTime) {
int idx = (t - startTime) / interval;
res.set(idx, res.get(idx) + 1);
}
}
return res;
}
}
class TweetCounts {
constructor() {
this.tweets = new Map();
}
recordTweet(tweetName, time) {
if (!this.tweets.has(tweetName)) {
this.tweets.set(tweetName, []);
}
this.tweets.get(tweetName).push(time);
}
getTweetCountsPerFrequency(freq, tweetName, startTime, endTime) {
let interval = freq === "minute" ? 60 : (freq === "hour" ? 3600 : 86400);
let times = this.tweets.get(tweetName) || [];
times.sort((a, b) => a - b);
let n_intervals = Math.floor((endTime - startTime) / interval) + 1;
let res = Array(n_intervals).fill(0);
for (let t of times) {
if (t >= startTime && t <= endTime) {
let idx = Math.floor((t - startTime) / interval);
res[idx]++;
}
}
return res;
}
}