A social media company is trying to monitor activity on their site by analyzing the number of tweets that occur in select periods of time. These periods can be partitioned into smaller time chunks based on a certain frequency (every minute, hour, or day).
For example, the period [10, 10000]
(in seconds) would be partitioned into the following time chunks with these frequencies:
- Every minute (60-second chunks):
[10,69]
,[70,129]
,[130,189]
,...
,[9970,10000]
- Every hour (3600-second chunks):
[10,3609]
,[3610,7209]
,[7210,10000]
- Every day (86400-second chunks):
[10,10000]
Notice that the last chunk may be shorter than the specified frequency's chunk size and will always end with the end time of the period (10000
in the above example).
Design and implement an API to help the company with their analysis.
Implement the TweetCounts
class:
TweetCounts()
Initializes theTweetCounts
object.void recordTweet(String tweetName, int time)
Stores thetweetName
at the recordedtime
(in seconds).List<Integer> getTweetCountsPerFrequency(String freq, String tweetName, int startTime, int endTime)
Returns a list of integers representing the number of tweets withtweetName
in each time chunk for the given period of time[startTime, endTime]
(in seconds) and frequencyfreq
.freq
is one of"minute"
,"hour"
, or"day"
representing a frequency of every minute, hour, or day respectively.
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); // New tweet "tweet3" at time 0 tweetCounts.recordTweet("tweet3", 60); // New tweet "tweet3" at time 60 tweetCounts.recordTweet("tweet3", 10); // New tweet "tweet3" at time 10 tweetCounts.getTweetCountsPerFrequency("minute", "tweet3", 0, 59); // return [2]; chunk [0,59] had 2 tweets tweetCounts.getTweetCountsPerFrequency("minute", "tweet3", 0, 60); // return [2,1]; chunk [0,59] had 2 tweets, chunk [60,60] had 1 tweet tweetCounts.recordTweet("tweet3", 120); // New tweet "tweet3" at time 120 tweetCounts.getTweetCountsPerFrequency("hour", "tweet3", 0, 210); // return [4]; chunk [0,210] had 4 tweets
思路:
2. HashMap<tweetName, TreeMap<timestamp, count>> 每一次插入 O(log N) query的时候统计落在每个时间段的count 用subMap 时间复杂度是 O(logN + k) k是落在时间段统计的个数
class TweetCounts {
private HashMap<String, TreeMap<Integer, Integer>> hashmap;
public TweetCounts() {
this.hashmap = new HashMap<>();
}
public void recordTweet(String tweetName, int time) {
hashmap.putIfAbsent(tweetName, new TreeMap<Integer, Integer>());
TreeMap<Integer, Integer> tweetMap = hashmap.get(tweetName);
tweetMap.put(time, tweetMap.getOrDefault(time, 0) + 1);
}
public List<Integer> getTweetCountsPerFrequency(String freq, String tweetName, int startTime, int endTime) {
List<Integer> res = new ArrayList<>();
int interval = 60;
if(freq.equals("hour")) {
interval = 60 * 60;
} else if(freq.equals("day")) {
interval = 60 * 60 * 24;
}
int size = (endTime - startTime) / interval + 1;
int[] bucket = new int[size];
TreeMap<Integer, Integer> tweetMap = hashmap.get(tweetName);
for(Integer time: tweetMap.subMap(startTime, endTime + 1).keySet()) {
int index = (time - startTime) / interval;
bucket[index] += tweetMap.get(time);
}
for(int i = 0; i < size; i++) {
res.add(bucket[i]);
}
return res;
}
}
/**
* Your TweetCounts object will be instantiated and called as such:
* TweetCounts obj = new TweetCounts();
* obj.recordTweet(tweetName,time);
* List<Integer> param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime);
*/
1. HashMap<tweetName, List<timestamp>> 每一次append一个tweet O(1) query的时候统计tweetName相应的所有timestamp 然后check落在哪个区间 O(n) 但是有一个问题就是要查所有的tweet不efficient
class TweetCounts {
HashMap<String, List<Integer>> hashmap;
public TweetCounts() {
this.hashmap = new HashMap<>();
}
// time is seconds;
public void recordTweet(String tweetName, int time) {
hashmap.putIfAbsent(tweetName, new ArrayList<Integer>());
hashmap.get(tweetName).add(time);
}
// fre is: min, hour, day.
public List<Integer> getTweetCountsPerFrequency(String freq, String tweetName, int startTime, int endTime) {
int interval = 60;
if(freq.equals("hour")) {
interval = 60 * 60;
} else if(freq.equals("day")) {
interval = 60 * 60 * 24;
}
List<Integer> res = new ArrayList<Integer>();
for(int i = 0; i < (endTime - startTime) / interval + 1; i++) {
res.add(0);
}
List<Integer> times = hashmap.get(tweetName);
for(int time: times) {
if(startTime <= time && time <= endTime) {
int index = (time - startTime) / interval;
res.set(index, res.get(index) + 1);
}
}
return res;
}
}
/**
* Your TweetCounts object will be instantiated and called as such:
* TweetCounts obj = new TweetCounts();
* obj.recordTweet(tweetName,time);
* List<Integer> param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime);
*/