300. Logger Rate Limiter
A stream of log lines hits your service, and identical messages must not spam the output. Build a class Logger with a single method should_print_message(timestamp, message) that decides, in real time, whether a message may print.
The rule: a message may print only if the same text has not printed within the previous 10 seconds. Once it prints at time t, that text is blocked until t + 10 — a call at exactly t + 10 is allowed again. Suppressed calls do not restart the countdown.
Calls arrive in order: timestamps are non-decreasing. Return true (print it) or false (drop it) for each call.
Example 1:
Input: should_print_message(1,"foo") · (2,"bar") · (3,"foo") · (8,"bar") · (10,"foo") · (11,"foo")
Output: true, true, false, false, false, true
Explanation: "foo" prints at t=1, blocking it until t=11 — so t=3 and t=10 are dropped, and t=11 is allowed. "bar" prints at t=2, blocking it until t=12, so t=8 is dropped.
Example 2:
Input: should_print_message(0,"spin") · (9,"spin") · (10,"spin") · (19,"spin")
Output: true, false, true, false
Explanation: Printed at t=0, "spin" unblocks at exactly t=10, so t=9 is dropped and t=10 prints. That print blocks it until t=20, dropping t=19.
Constraints:
- 1 ≤ q ≤ 10⁵ calls
- 0 ≤ timestamp ≤ 10⁹, and timestamps are non-decreasing across calls
- 1 ≤ message.length ≤ 30; messages are single words of letters, digits, dots, and dashes
Hints:
For each incoming message you need one fact fast: when did this exact text last print? That is a key → value question — a hash map from message to a time.
Store the *expiry* instead of the last print: map the message to `timestamp + 10` when it prints. A new call prints iff the message is absent or `timestamp >= expiry` — and suppressed calls simply never touch the map, so they can't extend the block.
▶ Run checks these sample cases. Submit also runs hidden edge cases.
Input: (1,"foo") · (2,"bar") · (3,"foo") · (8,"bar") · (10,"foo") · (11,"foo")
Expected output: true, true, false, false, false, true