Star

Leetcode 359. Logger Rate Limiter

Question:

Design a logger system that receive stream of messages along with its timestamps, each message should be printed if and only if it is not printed in the last 10 seconds.

Given a message and a timestamp (in seconds granularity), return true if the message should be printed in the given timestamp, otherwise returns false.

It is possible that several messages arrive roughly at the same time.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Logger logger = new Logger();
// logging string "foo" at timestamp 1
logger.shouldPrintMessage(1, "foo"); returns true;
// logging string "bar" at timestamp 2
logger.shouldPrintMessage(2,"bar"); returns true;
// logging string "foo" at timestamp 3
logger.shouldPrintMessage(3,"foo"); returns false;
// logging string "bar" at timestamp 8
logger.shouldPrintMessage(8,"bar"); returns false;
// logging string "foo" at timestamp 10
logger.shouldPrintMessage(10,"foo"); returns false;
// logging string "foo" at timestamp 11
logger.shouldPrintMessage(11,"foo"); returns true;

Explanation:

按照普通的hashmap存下所有值,然后更新timestamp是一种办法。但是实际中会浪费很多空间,所以比较好的方式其实是用queue存下最近timestamp在10以内的值,保持一个size最多为10的窗口就行。但是跑出来时间挺久的,用的空间少。

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class Log{
int timestamp;
String message;
public Log(int Timestamp, String Message) {
timestamp = Timestamp;
message = Message;
}
}
public class Logger {
/** Initialize your data structure here. */
PriorityQueue<Log> queue;
Set<String> set;
public Logger() {
queue = new PriorityQueue<>(10, new Comparator<Log>(){
public int compare(Log l1, Log l2){
return l1.timestamp - l2.timestamp;
}
});
set = new HashSet<>();
}
/** Returns true if the message should be printed in the given timestamp, otherwise returns false.
If this method returns false, the message will not be printed.
The timestamp is in seconds granularity. */
public boolean shouldPrintMessage(int timestamp, String message) {
while (queue.size() > 0) {
Log log = queue.peek();
if (timestamp - log.timestamp >= 10) {
Log pollLog = queue.poll();
set.remove(pollLog.message);
} else {
break;
}
}
boolean result = !set.contains(message);
if ( !set.contains(message)) {
queue.add(new Log(timestamp, message));
set.add(message);
}
return result;
}
}
/**
* Your Logger object will be instantiated and called as such:
* Logger obj = new Logger();
* boolean param_1 = obj.shouldPrintMessage(timestamp,message);
*/