Implement an LFU cache with O(1) operations
Company: Salesforce
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates a candidate's ability to design and implement efficient data structures for caching, including understanding frequency-based eviction policies, maintaining recency ordering for tie-breaking, and meeting strict time-complexity guarantees.
Constraints
- 0 <= capacity <= 10^5
- 0 <= len(operations) <= 2 * 10^5
- Each operation is either "put key value" or "get key"
- -10^9 <= key, value <= 10^9
Examples
Input: (2, ["put 1 1", "put 2 2", "get 1", "put 3 3", "get 2", "get 3", "get 1"])
Expected Output: [1, -1, 3, 1]
Explanation: After `get 1`, key 1 has frequency 2 while key 2 has frequency 1. Inserting key 3 evicts key 2. The later gets return -1, 3, and 1.
Input: (2, ["put 1 10", "put 2 20", "put 3 30", "get 1", "get 2", "get 3"])
Expected Output: [-1, 20, 30]
Explanation: Keys 1 and 2 both have frequency 1 when key 3 is inserted, so the least recently used among them, key 1, is evicted.
Input: (2, ["put 1 10", "put 2 20", "put 1 15", "put 3 30", "get 1", "get 2", "get 3"])
Expected Output: [15, -1, 30]
Explanation: Updating key 1 changes its value to 15 and increases its frequency. When key 3 is inserted, key 2 is evicted because it has the lower frequency.
Input: (0, ["put 1 1", "get 1", "put 2 2", "get 2"])
Expected Output: [-1, -1]
Explanation: With capacity 0, nothing can be stored, so every get returns -1.
Input: (3, ["put 1 1", "put 2 2", "put 3 3", "get 1", "get 2", "get 2", "put 4 4", "get 3", "get 4", "get 1", "get 2"])
Expected Output: [1, 2, 2, -1, 4, 1, 2]
Explanation: Before inserting key 4, key 3 is the only key with frequency 1, so it is evicted. The remaining gets reflect the updated values and frequencies.
Hints
- Use one hash map to store each key's current value and frequency.
- To break ties by recency in O(1), keep an ordered structure for each frequency and track the current minimum frequency.