Skip to content

LeetCode Rate Limiter Challenge#210

Merged
pertrai1 merged 1 commit into
mainfrom
leetcode-1222026
Jan 24, 2026
Merged

LeetCode Rate Limiter Challenge#210
pertrai1 merged 1 commit into
mainfrom
leetcode-1222026

Conversation

@pertrai1

@pertrai1 pertrai1 commented Jan 22, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Documentation

    • Updated the Logger Rate Limiter documentation with problem description and usage examples.
  • New Features

    • Logger class is now publicly exported and available for external use.

✏️ Tip: You can customize this high-level summary in your review settings.

@pertrai1 pertrai1 requested a review from Copilot January 22, 2026 14:38
@pertrai1 pertrai1 added the code challenge this is a coding challenge label Jan 22, 2026
@github-actions

Copy link
Copy Markdown

@codex review

1 similar comment
@github-actions

Copy link
Copy Markdown

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

1 similar comment
@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@github-actions

github-actions Bot commented Jan 22, 2026

Copy link
Copy Markdown

Claude finished @pertrai1's task in 2m 11s —— View job


LeetCode Solution Review ✅


📋 Review Summary

This PR reorganizes the Logger Rate Limiter solution (LeetCode #359) into the proper directory structure and makes minor TypeScript improvements. The solution is correct and efficient, implementing a Hash Map pattern for O(1) lookups.


✅ 1. Correctness Analysis

Status: CORRECT

The solution correctly handles all test cases and edge cases:

  • First occurrence: Messages are printed when seen for the first time
  • Rate limiting: Messages within 10 seconds are blocked
  • Exact boundary: At timestamp lastTimestamp + 10, messages are allowed (≥ comparison is correct)
  • Multiple messages: Different messages are tracked independently
  • Timestamp order: Works correctly with non-decreasing timestamps

Mental trace with example:

shouldPrintMessage(1, "foo")  → true  (new message, stored as {"foo": 1})
shouldPrintMessage(2, "bar")  → true  (new message, stored as {"bar": 2})
shouldPrintMessage(3, "foo")  → false (3 < 1+10=11)
shouldPrintMessage(11, "foo") → true  (11 >= 1+10=11, update to {"foo": 11})

⚡ 2. Complexity Analysis

Time Complexity: O(1) per operation

  • Map.has(): O(1)
  • Map.get(): O(1)
  • Map.set(): O(1)

Each shouldPrintMessage call performs at most 2 hash map operations, resulting in constant time.

Space Complexity: O(M) where M = unique messages

  • The messageMap stores one entry per unique message
  • With at most 10^4 calls and messages up to 30 characters, worst case is O(10^4) unique messages
  • This is optimal for this problem—you must store message timestamps to implement rate limiting

Note: A follow-up optimization could involve cleaning up old entries if timestamps are guaranteed to be chronological and we want to limit memory growth, but it's not necessary given the constraints.


🎯 3. DSA Pattern & Key Insights

Pattern: Hash Map (Dictionary)

This is a classic state tracking problem using a hash map to maintain the last seen timestamp for each message.

Why Hash Map?

  • We need O(1) lookups to check if a message was seen before
  • We need to store arbitrary string keys (messages) mapped to timestamps
  • Hash maps provide exactly this: fast key-value lookups

Key Insight 💡

The key insight is that we only need to store the LAST timestamp for each message, not all timestamps.

Since messages arrive in chronological order and we have a fixed 10-second window, we only care about the most recent occurrence. If currentTime >= lastTime + 10, we can safely print and update the entry.

This insight reduces the problem from potentially tracking all occurrences (which would be O(N) space per message) to just tracking the latest occurrence (O(1) space per message).

Common Mistakes ⚠️

  1. Using > instead of >=: The boundary case at exactly lastTimestamp + 10 should allow printing
  2. Not updating the timestamp: When printing at timestamp 11, you must update the map, or the next call at 12 would incorrectly succeed
  3. Over-engineering with cleanup logic: Given the constraints (10^4 calls max), cleanup is unnecessary and adds complexity

📝 4. Code Quality Review

Strengths ✓

  • Type safety: Using TypeScript with proper type annotations
  • Clear naming: messageMap, shouldPrintMessage, lastTimestamp are self-documenting
  • Non-null assertion: Correctly uses ! after get() since we've already checked has()
  • Export: Properly exports the class for testing/reuse

Minor Improvements

File: leetcode/easy/0359-logger-rate-limiter/logger-rate-limiter.ts:12-15

The else block is unnecessary since the if block returns early. This would be cleaner:

shouldPrintMessage(timestamp: number, message: string): boolean {
  if (this.messageMap.has(message)) {
    const lastTimestamp = this.messageMap.get(message)!;
    if (timestamp >= lastTimestamp + 10) {
      this.messageMap.set(message, timestamp);
      return true;
    }
    return false;
  }
  
  this.messageMap.set(message, timestamp);
  return true;
}

This reduces nesting depth and follows the "early return" pattern common in guard clauses.

Optional: Consider adding a brief comment explaining the rate limiting logic:

// Rate limit: Only print if 10+ seconds have passed since last occurrence
if (timestamp >= lastTimestamp + 10) {

🔗 5. Related Problems

To practice the Hash Map state tracking pattern, try these similar problems:

  1. LeetCode 1146 - Snapshot Array (Medium)

    • Pattern: Hash map for tracking versions/state over time
    • Key similarity: Storing historical state indexed by an identifier
  2. LeetCode 346 - Moving Average from Data Stream (Easy)

    • Pattern: State tracking with time windows
    • Key similarity: Maintaining state over a sliding time window
  3. LeetCode 362 - Design Hit Counter (Medium)

    • Pattern: Time-windowed state tracking
    • Key similarity: Counting events within a time window, chronological guarantees
  4. LeetCode 981 - Time Based Key-Value Store (Medium)

    • Pattern: Hash map + binary search for temporal data
    • Key similarity: Associating values with timestamps

🎓 6. Learning Summary

Core Concepts from This Problem

  • Hash map for O(1) state tracking: When you need to remember information about arbitrary keys
  • Time-based rate limiting: Only need to store the last occurrence, not all history
  • Boundary conditions: Be careful with >= vs > in time comparisons
  • Chronological guarantees: Can simplify logic when timestamps are non-decreasing

Problem Classification

  • Type: Design, Hash Table
  • Difficulty: Easy
  • Interview frequency: Medium (good warmup for system design rate limiters)

Real-World Applications

This pattern appears in:

  • API rate limiting: Throttling requests per user/IP
  • Spam detection: Preventing duplicate messages
  • Event deduplication: Ensuring events aren't processed multiple times
  • Logging systems: Preventing log spam

🏆 Final Assessment

Category Rating Notes
Correctness ✅ Excellent Handles all cases including boundaries
Efficiency ✅ Optimal O(1) time, O(M) space—can't do better
Code Quality ✅ Good Clean TypeScript, minor style improvement possible
Pattern Recognition ✅ Clear Straightforward hash map application

Overall: This is a solid, production-ready solution that demonstrates understanding of hash maps for state tracking. The only improvement would be removing the unnecessary else block for cleaner code style.

Great work organizing the solution into the proper directory structure! The TypeScript improvements (adding export and the non-null assertion !) make the code more maintainable.


@github-actions

github-actions Bot commented Jan 22, 2026

Copy link
Copy Markdown

🧮 Solution Analysis

PR: LeetCode Rate Limiter Challenge
Files Changed: leetcode/easy/0359-logger-rate-limiter/logger-rate-limiter.ts

📊 Code Quality Results

ESLint Analysis

  • Errors: 0
  • Warnings: 0

🔍 Complexity Analysis

💡 Analysis Tips

  • Time Complexity: Focus on the dominant operation in loops
  • Space Complexity: Consider auxiliary data structures
  • Optimization: Look for opportunities to improve efficiency
  • Edge Cases: Ensure your solution handles empty inputs, null/undefined, edge conditions

📁 Analysis Files Created

Detailed analysis files have been automatically generated and committed to docs/analysis/ for future reference.

🎯 Next Steps

  1. Review any ESLint errors/warnings above
  2. Consider the complexity analysis - is this the optimal approach?
  3. Test with edge cases mentioned in the problem description
  4. Add comments explaining complex logic
  5. Check the docs/analysis/ directory for detailed complexity analysis files

Analysis generated for PR files only

@coderabbitai

coderabbitai Bot commented Jan 22, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Documentation for the Logger Rate Limiter problem is reorganized from a root-level directory to the leetcode/easy subdirectory structure. The Logger class is now publicly exported, and type safety is improved with a non-null assertion on message timestamp retrieval.

Changes

Cohort / File(s) Summary
Documentation Reorganization
0359-logger-rate-limiter/README.md, leetcode/easy/0359-logger-rate-limiter/README.md
Root-level README deleted (45 lines); new README added to leetcode/easy subdirectory (50 lines) describing Logger Rate Limiter problem, class interface, constraints, and usage examples.
Logger Implementation
leetcode/easy/0359-logger-rate-limiter/logger-rate-limiter.ts
Logger class made publicly exported with export keyword; non-null assertion (!) added to this.messageMap.get(message) retrieval for stricter typing.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A logger hops into the light,
Now exported, shining bright!
Types asserted, docs rearranged,
The leetcode warren's been exchanged!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'LeetCode Rate Limiter Challenge' is generic and vague. It refers to the general category (LeetCode challenge) but doesn't clearly specify the primary change, which involves adding/modifying README documentation and exporting the Logger class. Consider a more specific title like 'Add Logger Rate Limiter documentation and export class' that clearly conveys the main changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch leetcode-1222026

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown

🤖 Gemini Code Review (Model: gemini-2.5-flash)

Here's a review of your LeetCode solution for the "Logger Rate Limiter" problem:


1. Pattern Identification

This solution primarily uses the Hash Map (or Dictionary) pattern. It leverages a hash map to store and retrieve the last-printed timestamp for each unique message efficiently. This pattern is fundamental for problems requiring quick lookups, frequency counting, or state management associated with unique keys.

2. Complexity Verification

  • Time Complexity: O(1) on average per shouldPrintMessage call.

    • Logger(): Initializing a Map is an O(1) operation.
    • shouldPrintMessage(timestamp, message): Map.has(), Map.get(), and Map.set() operations for strings typically take O(1) time on average. In the worst-case scenario (due to hash collisions or very long strings causing expensive hashing), these operations could degrade to O(L) where L is the length of the message string, or even O(N) if the map implementation is poor and all keys hash to the same bucket. However, for well-implemented hash maps and typical string lengths (up to 30 as per constraints), O(1) average is a safe assumption.
    • The total time complexity for K calls would therefore be O(K) on average.
  • Space Complexity: O(U * L)

    • U is the number of unique messages encountered.
    • L is the maximum length of a message string (constrained to 30).
    • In the worst case, all 10^4 calls to shouldPrintMessage could be for 10^4 distinct messages. Each message string (up to 30 characters) and its associated timestamp (an integer) would be stored in the map. Thus, the space complexity is proportional to the total size of unique messages stored.

3. Key Insight

The key insight is to realize that for each message, we only care about the next allowable timestamp after it has been printed. Instead of storing just a boolean "has been printed recently," we store the specific timestamp t + 10 for a message printed at t.

When a new request for message at timestamp arrives:

  1. Check if message has ever been printed before (i.e., is it in our map?).
  2. If it hasn't, print it and store timestamp + 10 as its next allowed print time.
  3. If it has, retrieve its nextAllowedTimestamp.
  4. If the current timestamp is greater than or equal to nextAllowedTimestamp, then it's safe to print. Update the stored value to timestamp + 10.
  5. Otherwise, the message is still rate-limited, so don't print.

This simple comparison timestamp >= nextAllowedTimestamp is the core logic that efficiently enforces the 10-second rule.

4. Edge Case Analysis

The current solution handles edge cases correctly:

  • First occurrence of a message: The messageMap.has(message) check correctly identifies new messages, allowing them to be printed and their nextAllowedTimestamp stored.
  • timestamp = 0: The logic timestamp >= lastTimestamp + 10 still holds. For timestamp = 0, if it's the first message, it's printed. If it's a subsequent message and lastTimestamp was negative (not possible here) or 0 - 10 (if lastTimestamp was 0), the math still works.
  • Messages arriving at the same timestamp: The problem states "Several messages may arrive at the same timestamp." The solution handles this fine because the check timestamp >= lastTimestamp + 10 is absolute. If message "foo" was printed at t=1 (next allowed t=11), and another message "foo" arrives at t=3, it's correctly blocked. If message "bar" arrives at t=3, it's treated independently.
  • Large timestamps: timestamp up to 10^9 is handled by JavaScript's number type without overflow.
  • message.length constraints: 1 <= message.length <= 30 ensures messages are valid and not excessively long, which helps maintain the O(1) average time complexity for hash map operations.

5. Learning Points

  • Similar problems using this pattern:

    • LRU Cache: While more complex, LRU cache implementations often use a hash map combined with a doubly linked list to track usage frequency and eviction.
    • Two Sum: A classic problem where a hash map is used to store numbers and their indices for O(N) lookup.
    • First Unique Character in a String: Hash map to count character frequencies.
    • Word Frequency Counter: Similar to above, counting occurrences of strings.
    • Debouncing/Throttling implementations: In frontend development, these techniques often use a similar principle of tracking the "last executed" or "next allowed" time for a function call.
  • Common mistakes people make with this pattern:

    • Not using a hash map: Trying to store messages in an array and iterating through it for each check, leading to O(N) time complexity per call instead of O(1).
    • Incorrectly calculating the "next allowed" time: Forgetting the + 10 or misinterpreting the comparison logic.
    • Forgetting to update the timestamp: If a message is printed, its nextAllowedTimestamp must be updated in the map, otherwise it will be incorrectly allowed or blocked in subsequent calls.
    • Hash collision awareness: While less common in interviews for standard library hash maps, understanding that worst-case hash collisions can degrade performance is crucial for deeper understanding.
  • Variations of this problem:

    • Different rate limiting rules: Instead of "every 10 seconds," it could be "at most 5 messages per 60 seconds" (this would require a queue of timestamps per message, or a sliding window approach).
    • Global rate limit: Limiting the total number of messages printed across all types within a time window.
    • Memory constraints: If the number of unique messages was extremely large but only a few were active at any given time, one might need to evict old messages from the map (e.g., using a Queue to track messages older than 10 seconds and removing them).
    • Concurrency: If shouldPrintMessage could be called concurrently, thread-safe access to the map would be necessary.

6. Code Quality

The code quality is excellent:

  • Variable Naming: messageMap is clear and descriptive. timestamp and message are standard. lastTimestamp is also appropriate.
  • Code Structure: The Logger class is well-defined. The shouldPrintMessage method is concise and focused on its single responsibility.
  • Readability: The logic is straightforward and easy to follow.
  • TypeScript Specifics:
    • export class Logger: Good for modularity if this class were part of a larger module.
    • messageMap = new Map<string, number>();: Type inference is good, but explicit generics Map<string, number> is even better for clarity.
    • const lastTimestamp = this.messageMap.get(message)!;: The ! (non-null assertion operator) is used here. It's safe because this.messageMap.get(message) is only called after this.messageMap.has(message) has returned true, guaranteeing lastTimestamp will be a number. This is a common and acceptable pattern in TypeScript when type safety is guaranteed by preceding logic.

7. Alternative Approaches

  1. Using a Queue (or Deque) and a Hash Set for Memory Optimization:

    • Approach: Maintain a Map<string, number> (like your current solution) to store the nextAllowedTimestamp for each message. Additionally, use a Queue (e.g., Array in JS, or LinkedList) to store [timestamp, message] pairs for all messages that have been printed within the last 10 seconds. When shouldPrintMessage is called, first "clean up" the queue by removing all entries whose timestamp + 10 is less than the current timestamp. This keeps the queue (and potentially a companion Set of active messages) lean. Then, proceed with the hash map check.
    • Trade-offs:
      • Space: Can be more space-efficient if the total number of unique messages encountered over time is very large, but the number of active unique messages (those printed within the last 10 seconds) is relatively small. The queue and companion set would only store active messages.
      • Time: Map operations remain O(1) average. The queue cleanup operation could be O(K_active) in the worst case (where K_active is the number of messages in the queue) if there's a large jump in timestamp. However, if timestamps arrive somewhat regularly, it's amortized O(1).
      • Complexity: More complex to implement and debug than the simple map approach.
    • Why not used here?: For the given constraints (at most 10^4 calls, which implies at most 10^4 unique messages), the space usage of the simple Map is perfectly acceptable and the performance is consistently O(1) per call, making it the optimal choice.
  2. Using a Min-Heap (Priority Queue) with a Hash Map:

    • Approach: Store [nextAllowedTimestamp, message] pairs in a min-heap, ordered by nextAllowedTimestamp. The hash map would store the current nextAllowedTimestamp for quick lookup. Before checking a message, pop elements from the heap that are no longer valid (their nextAllowedTimestamp is past the current timestamp).
    • Trade-offs:
      • Space: Similar to the Map-only approach, O(U * L).
      • Time: Map operations are O(1) average. Heap operations (insert, delete-min) are O(log U). So, shouldPrintMessage would be O(log U) per call.
      • Complexity: Significantly more complex than the hash map approach, and slower. Not suitable here.

The current solution using just a Map is the most straightforward and efficient approach for the given problem constraints.

@github-actions

Copy link
Copy Markdown

🤖 Gemini Code Review (Model: gemini-2.5-flash)

Here's a review of your Logger Rate Limiter solution, focusing on educational insights and potential improvements.


1. Pattern Identification

This problem primarily uses a Hash Map (or Dictionary/Object in other languages) to store and retrieve state efficiently. It falls under the Design problem category, where the goal is to implement a class with specific functional requirements and performance characteristics.

2. Complexity Verification

  • Time Complexity:

    • Stated: Not explicitly stated in the code.
    • Correct: O(1) on average for each call to shouldPrintMessage.
      • Map.has(), Map.get(), and Map.set() operations typically have an average time complexity of O(1). In the worst-case scenario (due to hash collisions), these operations could degrade to O(L) where L is the length of the message string (for hashing the key) or even O(N) where N is the number of entries in the map, but for practical purposes with well-designed hash functions and string keys, O(1) average is expected.
      • The Logger() constructor takes O(1) time to initialize the map.
  • Space Complexity:

    • Stated: Not explicitly stated in the code.
    • Correct: O(M) where M is the number of unique messages encountered throughout the lifetime of the logger.
      • The messageMap stores one entry for each unique message that has ever been printed. In the worst case, if all 10^4 calls to shouldPrintMessage involve a unique message, the map could store up to 10^4 entries.

3. Key Insight

The key insight for this problem is to efficiently track the next allowed timestamp for each unique message. Instead of just storing the last time a message was printed and then recalculating lastTimestamp + 10, it's often more intuitive and slightly cleaner to store the earliest timestamp at which a message can be printed again.

When a message arrives:

  1. Check if the message has been seen before (i.e., is in our map).
  2. If it hasn't been seen, it's the first time, so print it and store its currentTimestamp + 10 as its next allowed print time.
  3. If it has been seen, compare the current timestamp with its stored nextAllowedPrintTime.
    • If currentTimestamp >= nextAllowedPrintTime, then it's okay to print. Update its nextAllowedPrintTime to currentTimestamp + 10.
    • If currentTimestamp < nextAllowedPrintTime, then it's still in its cooldown period, so do not print.

4. Edge Case Analysis

The current solution correctly handles several edge cases due to its straightforward logic:

  • First occurrence of a message: The else block this.messageMap.set(message, timestamp); return true; correctly handles this, ensuring the first instance of any message is always printed.
  • Messages with the same timestamp: "Several messages may arrive at the same timestamp." This is handled correctly because each message is a unique key in the map, so their rate limits are independent.
  • Timestamp 0: If the first message arrives at timestamp = 0, it will be printed, and its next allowed print time will be 0 + 10 = 10. This is correct.
  • Messages never printed for a long time: The logic still holds. If a message was last printed at t and its next allowed print time was t+10, and then it reappears at t+100, t+100 >= t+10 will be true, and it will print, updating its next allowed time to t+100+10.
  • Chronological Order: The constraint that timestamp is non-decreasing is crucial and the solution relies on it. If timestamps could arrive out of order, the logic would need significant modification (e.g., using a Min-Heap or a more complex data structure to handle past/future messages).

The solution appears robust for the given constraints.

5. Learning Points

  • Similar Problems:
    • API Rate Limiters: Many systems require rate limiting for API calls (e.g., "no more than 100 requests per minute per user"). The core idea of tracking timestamps for specific identifiers is the same.
    • Caching with Time-based Invalidation: Problems where cached data expires after a certain duration.
    • Debouncing/Throttling: Common techniques in frontend development to control how often a function is executed (e.g., preventing too many rapid API calls on user input).
  • Common Mistakes:
    • Incorrectly updating the timestamp: Forgetting to update the map entry after a message is printed, leading to incorrect future decisions.
    • Using an inefficient data structure: Opting for an array or list and iterating through it to find message statuses, which would lead to O(N) per shouldPrintMessage call instead of O(1).
    • Misinterpreting "every 10 seconds": Some might incorrectly calculate timestamp - lastPrintedTime < 10 instead of focusing on the nextAllowedPrintTime. Your current approach timestamp >= lastTimestamp + 10 is equivalent and correct.
  • Variations:
    • Global Rate Limiting: Instead of per-message, limit the total number of messages printed in a given window (e.g., "no more than 5 messages in any 10-second window"). This would typically involve a queue to track all recent messages and a sliding window approach.
    • Different Cooldowns: Each message type could have its own cooldown period. The map value would then need to be an object containing both the nextPrintTime and the cooldownDuration.
    • Bursting: Allow a certain number of messages to print immediately, then enforce the cooldown. This would require tracking a counter along with the timestamp.

6. Code Quality

  • Variable Naming:

    • messageMap is clear.
    • timestamp and message are standard and clear.
    • lastTimestamp is also descriptive.
  • Code Structure and Readability:

    • The class structure is appropriate.
    • The if/else logic is easy to follow.
    • The use of ! (lastTimestamp = this.messageMap.get(message)!;) is a TypeScript non-null assertion. It's safe here because this.messageMap.has(message) guarantees that get() will return a number, not undefined.
  • Minor Improvement - Refactoring for Conciseness:
    The logic can be slightly refactored to reduce repetition and potentially improve clarity by explicitly storing the next allowed print time rather than the last printed time.

    export class Logger {
      // Stores message -> timestamp_when_it_can_print_again
      // Using 'private' is good practice for internal class members.
      private messageCooldowns: Map<string, number>;
    
      constructor() {
        this.messageCooldowns = new Map<string, number>();
      }
    
      shouldPrintMessage(timestamp: number, message: string): boolean {
        const nextPrintTime = this.messageCooldowns.get(message);
    
        // If the message has not been printed before (nextPrintTime is undefined)
        // OR if the current timestamp is at or after its next allowed print time
        if (nextPrintTime === undefined || timestamp >= nextPrintTime) {
          // It's allowed to print. Update its next allowed print time.
          this.messageCooldowns.set(message, timestamp + 10);
          return true;
        } else {
          // Message is still in cooldown
          return false;
        }
      }
    }

    This version:

    • Renames messageMap to messageCooldowns to better reflect what the stored value (number) represents.
    • Explicitly initializes the map in a constructor, which is good practice.
    • Checks for undefined directly from Map.get() to avoid the has() call, making it slightly more concise.
    • Stores timestamp + 10 directly, which is the "next allowed print time", aligning with the "key insight".

7. Alternative Approaches

  1. Using a Queue + Set (for different problem variations):

    • Approach: Maintain a Queue of [timestamp, message] pairs for all messages printed within the last 10 seconds. Additionally, maintain a Set of messages that are currently "active" (i.e., present in the queue).
    • Trade-offs:
      • Time: O(K) in the worst case for dequeueing old messages (where K is the number of messages in the 10-second window), but O(1) amortized. Set operations are O(1) average.
      • Space: O(K) where K is the number of messages printed within any 10-second window.
      • Suitability: This approach is more complex and less efficient for this specific problem where we only care about the last print time of each unique message. It's better suited for problems involving global rate limits (e.g., "no more than X total messages in any 10-second window") or when you need to expire messages that haven't been seen recently, rather than tracking indefinitely.
  2. Trie (Overkill for this problem):

    • Approach: If the message strings were extremely long and shared many common prefixes, a Trie could be used to store the nextPrintTime at the leaf nodes (or along paths).
    • Trade-offs:
      • Time: Lookups would be O(L) where L is the length of the message string, potentially slower than O(1) average for a hash map.
      • Space: Could potentially save space if there's very high prefix overlap among very long strings.
      • Suitability: For message lengths up to 30 characters, the overhead and complexity of a Trie generally outweigh any benefits compared to a standard hash map, which offers O(1) average time complexity for string hashing.

The current Map-based approach is indeed the most optimal and straightforward for this specific problem statement.

@github-actions

Copy link
Copy Markdown

✅ Test Results

Tests have been executed for this pull request.

📊 Coverage Summary

Metric Coverage
Statements 94.61%
Branches 89.26%
Functions 85.71%
Lines 94.68%

Check the workflow logs for detailed test output.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new LeetCode Easy problem solution for "Logger Rate Limiter" (problem #0359). The solution implements a rate limiting system that prevents duplicate messages from being printed within a 10-second window.

Changes:

  • Added TypeScript implementation with hash map-based rate limiting logic
  • Added comprehensive README with problem description, examples, and constraints
  • Migrated README from incorrect root location to proper directory structure

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
leetcode/easy/0359-logger-rate-limiter/logger-rate-limiter.ts Implements Logger class with export keyword and non-null assertion for type safety
leetcode/easy/0359-logger-rate-limiter/README.md Adds well-formatted problem documentation with examples and constraints
0359-logger-rate-limiter/README.md Removes incorrectly placed README from root directory

@pertrai1 pertrai1 merged commit 68cda4a into main Jan 24, 2026
15 of 16 checks passed
@pertrai1 pertrai1 deleted the leetcode-1222026 branch January 24, 2026 12:48
@github-actions

Copy link
Copy Markdown

📅 Spaced Repetition Reviews Scheduled!

Great job solving #0359 - Logger Rate Limiter! 🎉

To help you retain this knowledge long-term, I've scheduled 5 review sessions using spaced repetition:

Review Interval Schedule Logic
1st Review 1 day after solving Scheduled now
2nd Review 3 days after 1st review Auto-scheduled when 1st completes
3rd Review 7 days after 2nd review Auto-scheduled when 2nd completes
4th Review 14 days after 3rd review Auto-scheduled when 3rd completes
5th Review 30 days after 4th review Auto-scheduled when 4th completes

What to expect:

  • Your 1st review is scheduled for tomorrow
  • Each subsequent review is scheduled automatically when you complete the previous one
  • This ensures proper spacing even if you complete a review a few days late
  • GitHub issues will be created automatically for each review
  • Each issue will link back to your solution

🧠 Why Spaced Repetition?

Research shows that reviewing material at increasing intervals dramatically improves retention. This adaptive scheduling ensures optimal spacing based on when you actually complete each review!

Check docs/reviews/review-schedule.json to see your review schedule.

github-actions Bot pushed a commit that referenced this pull request Jan 24, 2026
  Problem: #0359 - Logger Rate Limiter
  PR: #210
  First review scheduled (subsequent reviews auto-scheduled on completion)

  [skip ci]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

code challenge this is a coding challenge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants