LeetCode 359: Logger Rate Limiter Solution

LeetCode 359, Logger Rate Limiter, asks you to build a logger that prints each unique message at most once every 10 seconds. A repeat inside that window is dropped.

One method does the work. shouldPrintMessage(timestamp, message) returns true if the message should print now, and false if it is too soon.

The problem

Timestamps arrive in seconds and never go backwards. Two calls can share the same second.

A message may print again once 10 or more seconds have passed since its last print. Exactly 10 seconds counts as allowed.

Different messages never block each other. The window is tracked per message, not for the logger as a whole.

Example

CallResultReason
shouldPrintMessage(1, "foo")trueFirst time seen.
shouldPrintMessage(2, "bar")trueFirst time seen.
shouldPrintMessage(3, "foo")falseOnly 2 seconds since "foo" printed.
shouldPrintMessage(8, "bar")falseOnly 6 seconds since "bar" printed.
shouldPrintMessage(10, "foo")falseOnly 9 seconds since "foo" printed.
shouldPrintMessage(11, "foo")trueA full 10 seconds have passed.

Constraints

  • The timestamp is between 0 and 10 to the power of 9.
  • Timestamps are passed in non-decreasing order.
  • Each message has 1 to 30 characters.
  • At most 10,000 calls are made.

Approach 1: a hash map of last print times

Keep a map from each message to the second it last printed.

On a call, look the message up. If the map has no entry, print it and store the timestamp.

If an entry exists, subtract. When timestamp - last is under 10, return false and change nothing stored.

Otherwise store the new timestamp and return true. A hash map answers each call in constant time on average.

Python3
Python3

. . . .

The Python code above keeps a dictionary called last_print. Each key is a message and each value is the second that message last printed.

One detail decides whether the solution passes.

The stored time is updated only when the message actually prints. If you update it on every call, a message repeated every second would never print again.

That is the most common bug in this question. The window starts at the last print, not at the last attempt.

Java, approach 1

Java
Java

. . . .

The Java version uses a HashMap<String, Integer>. It follows the same three steps as the Python version.

A missing key means the message has never printed. containsKey handles that case before any subtraction runs.

Space is O(m), where m is the number of distinct messages ever seen. Nothing is removed, so the map only grows.

For this question that is fine, because at most 10,000 calls are made. For a logger running for months it is not. That limitation leads to the second approach.

Approach 2: a queue plus a set

This version stores only the messages still inside the 10-second window. Memory then depends on current traffic, not on history.

Keep a queue of timestamp and message pairs in arrival order. Keep a set holding the same messages for fast lookup.

On each call, first remove every pair at the front of the queue whose timestamp is 10 or more seconds old. Remove each of those messages from the set as well.

Then check the set. If the message is present, return false.

If it is absent, add it to the queue and to the set, then return true.

Python, approach 2

Python3
Python3

. . . .

The Python code above uses collections.deque for the queue and a plain set for lookup.

The purge loop runs before the membership check. Without it, an expired entry would block a message that should print.

The set exists only for speed. Scanning the queue would give the same answer, but each call would cost O(k) instead of O(1).

Each pair enters the queue once and leaves it once. Averaged over many calls, the cost is constant.

Java, approach 2

Java
Java

. . . .

The Java version uses an ArrayDeque for the queue and a HashSet for lookup. A small pair class holds the timestamp and the message together.

An int[] of length two plus a parallel list of strings works just as well if you prefer no extra class.

Cost of each approach

ApproachTime per callExtra space
Hash mapO(1) on averageO(m), every distinct message ever seen
Queue plus setO(1) averaged over callsO(k), messages inside the last 10 seconds

One call in approach 2 can be slow. If many entries expire at the same moment, that single call removes all of them.

The average stays constant, because each entry is removed exactly once across the whole run.

Which one to give in an interview

Give the hash map first. It is shorter, it is what the question expects, and it is easier to get right under time pressure.

Then say that the map never forgets a message, so memory grows with the number of distinct messages. Offer the queue version as the fix.

Naming that trade-off is what turns a correct answer into a strong one.

Edge cases to check

  • Two calls in the same second with the same message. The second one returns false.
  • A gap of exactly 10 seconds. It returns true, because the rule is "at least 10".
  • Two different messages at the same timestamp. Both return true.
  • A long run of one message. Only the first call in each window prints.
  • Many threads calling at once. The question is single threaded, but say how you would lock the map if asked.

How to Prepare

TAGS
Coding Interview
CONTRIBUTOR
Arslan Ahmad
Arslan Ahmad
ex-FAANG engineering manager and author or Grokking series.

GET YOUR FREE

Coding Questions Catalog

Design Gurus Newsletter - Latest from our Blog
Boost your coding skills with our essential coding questions catalog.
Take a step towards a better tech career now!
Explore Answers
286. Walls and Gates - Detailed Explanation
Learn to solve Leetcode 286. Walls and Gates with multiple approaches.
362. Design Hit Counter - Detailed Explanation
Learn to solve Leetcode 362. Design Hit Counter with multiple approaches.
1086. High Five - Detailed Explanation
Learn to solve Leetcode 1086. High Five with multiple approaches.
51. N-Queens - Detailed Explanation
Learn to solve Leetcode 51. N-Queens with multiple approaches.
176. Second Highest Salary - Detailed Explanation
Learn to solve Leetcode 176. Second Highest Salary with multiple approaches.
198. House Robber - Detailed Explanation
Learn to solve Leetcode 198. House Robber with multiple approaches.
Related Courses
New
Grokking the AI System Design Interview course cover
Grokking the AI System Design Interview
Learn to design AI systems the way interviewers expect: classic ML products, LLM and RAG architectures, and agentic systems, all through the lens of the system design interview.
4.6
(3,192 learners)
Discounted price for Your Region

$123

Grokking the Coding Interview: Patterns for Coding Questions course cover
Grokking the Coding Interview: Patterns for Coding Questions
The 24 essential patterns behind every coding interview question. Available in Java, Python, JavaScript, C++, C#, and Go. The most comprehensive coding interview course with 543 lessons. A smarter alternative to grinding LeetCode.
4.6
Discounted price for Your Region

$197

Grokking Modern AI Fundamentals course cover
Grokking Modern AI Fundamentals
Master the fundamentals of AI today to lead the tech revolution of tomorrow.
4.1
Discounted price for Your Region

$72

Design Gurus logo
One-Stop Portal For Tech Interviews.
Copyright © 2026 Design Gurus, LLC. All rights reserved.