Implement the class TweetCounts
that supports two methods:
1. recordTweet(string tweetName, int time)
tweetName
at the recorded time
(in seconds).2. getTweetCountsPerFrequency(string freq, string tweetName, int startTime, int endTime)
tweetName
per minute, hour, or day (depending on freq
) starting from the startTime
(in seconds) and ending at the endTime
(in seconds).freq
is always minute, hour or day, representing the time interval to get the total number of occurrences for the given tweetName
.startTime
, so the time intervals are [startTime, startTime + delta*1>, [startTime + delta*1, startTime + delta*2>, [startTime + delta*2, startTime + delta*3>, ... , [startTime + delta*i, min(startTime + delta*(i+1), endTime + 1)>
for some non-negative number i
and delta
(which depends on freq
).
Example:
Input ["TweetCounts","recordTweet","recordTweet","recordTweet","getTweetCountsPerFrequency","getTweetCountsPerFrequency","recordTweet","getTweetCountsPerFrequency"] [[],["tweet3",0],["tweet3",60],["tweet3",10],["minute","tweet3",0,59],["minute","tweet3",0,60],["tweet3",120],["hour","tweet3",0,210]] Output [null,null,null,null,[2],[2,1],null,[4]] Explanation TweetCounts tweetCounts = new TweetCounts(); tweetCounts.recordTweet("tweet3", 0); tweetCounts.recordTweet("tweet3", 60); tweetCounts.recordTweet("tweet3", 10); // All tweets correspond to "tweet3" with recorded times at 0, 10 and 60. tweetCounts.getTweetCountsPerFrequency("minute", "tweet3", 0, 59); // return [2]. The frequency is per minute (60 seconds), so there is one interval of time: 1) [0, 60> - > 2 tweets. tweetCounts.getTweetCountsPerFrequency("minute", "tweet3", 0, 60); // return [2, 1]. The frequency is per minute (60 seconds), so there are two intervals of time: 1) [0, 60> - > 2 tweets, and 2) [60,61> - > 1 tweet. tweetCounts.recordTweet("tweet3", 120); // All tweets correspond to "tweet3" with recorded times at 0, 10, 60 and 120. tweetCounts.getTweetCountsPerFrequency("hour", "tweet3", 0, 210); // return [4]. The frequency is per hour (3600 seconds), so there is one interval of time: 1) [0, 211> - > 4 tweets.
Constraints:
10000
operations considering both recordTweet
and getTweetCountsPerFrequency
.0 <= time, startTime, endTime <= 10^9
0 <= endTime - startTime <= 10^4
use std::collections::BTreeMap;
use std::collections::HashMap;
const SECONDS: [usize; 3] = [60, 3600, 86400];
#[derive(Default)]
struct TweetCounts {
data: HashMap<String, BTreeMap<usize, usize>>,
}
impl TweetCounts {
fn new() -> Self {
TweetCounts::default()
}
fn record_tweet(&mut self, tweet_name: String, time: i32) {
let time = time as usize;
*self
.data
.entry(tweet_name)
.or_default()
.entry(time)
.or_default() += 1;
}
fn get_tweet_counts_per_frequency(
&self,
freq: String,
tweet_name: String,
start_time: i32,
end_time: i32,
) -> Vec<i32> {
let seconds = SECONDS[Self::freq_to_index(&freq)];
let start_time = start_time as usize;
let end_time = end_time as usize;
let n = (end_time - start_time) / seconds + 1;
let mut res = vec![0; n];
if let Some(counts) = self.data.get(&tweet_name) {
for (&t, &c) in counts {
let i = (t - start_time) / seconds;
if t >= start_time && t <= end_time {
res[i] += c as i32;
}
}
}
res
}
fn freq_to_index(freq: &str) -> usize {
match freq {
"minute" => 0,
"hour" => 1,
"day" => 2,
_ => panic!(),
}
}
}
#[test]
fn test() {
let mut obj = TweetCounts::new();
obj.record_tweet("tweet3".to_string(), 0);
obj.record_tweet("tweet3".to_string(), 60);
obj.record_tweet("tweet3".to_string(), 10);
assert_eq!(
obj.get_tweet_counts_per_frequency("minute".to_string(), "tweet3".to_string(), 0, 59),
vec![2]
);
assert_eq!(
obj.get_tweet_counts_per_frequency("minute".to_string(), "tweet3".to_string(), 0, 60),
vec![2, 1]
);
obj.record_tweet("tweet3".to_string(), 120);
assert_eq!(
obj.get_tweet_counts_per_frequency("hour".to_string(), "tweet3".to_string(), 0, 210),
vec![4]
);
}