Implement an LFU Cache
Company: Cisco
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Technical Screen
Quick Answer: This question evaluates understanding of algorithmic design and data structure management for cache eviction policies, focusing on frequency- and recency-based bookkeeping and meeting average O(1) time constraints.
Constraints
- 1 <= len(operations) == len(arguments) <= 200000
- operations[0] == "LFUCache" and arguments[0] has exactly 1 integer
- For i > 0, operations[i] is either "put" or "get"
- 0 <= capacity <= 100000
- -10^9 <= key, value <= 10^9
- Average time complexity of both get and put should be O(1)
Examples
Input: (['LFUCache', 'put', 'put', 'get', 'put', 'get', 'get'], [[2], [1, 1], [2, 2], [1], [3, 3], [2], [3]])
Expected Output: [None, None, None, 1, None, -1, 3]
Explanation: After `get(1)`, key 1 has frequency 2 while key 2 has frequency 1. Inserting key 3 evicts key 2.
Input: (['LFUCache', 'put', 'put', 'put', 'get', 'get', 'get'], [[2], [1, 10], [2, 20], [3, 30], [1], [2], [3]])
Expected Output: [None, None, None, None, -1, 20, 30]
Explanation: Before inserting key 3, keys 1 and 2 both have frequency 1. Key 1 is less recent, so it is evicted.
Input: (['LFUCache', 'put', 'put', 'put', 'put', 'get', 'get', 'get'], [[2], [1, 1], [2, 2], [2, 20], [3, 3], [1], [2], [3]])
Expected Output: [None, None, None, None, None, -1, 20, 3]
Explanation: Updating key 2 increases its frequency, so key 1 remains the least frequently used and is evicted when key 3 is inserted.
Input: (['LFUCache', 'put', 'get', 'put', 'get'], [[0], [1, 1], [1], [2, 2], [2]])
Expected Output: [None, None, -1, None, -1]
Explanation: With capacity 0, every put is ignored and every get returns -1.
Input: (['LFUCache', 'put', 'put', 'get', 'get', 'put', 'get', 'get', 'get'], [[2], [1, 1], [2, 2], [1], [2], [3, 3], [1], [2], [3]])
Expected Output: [None, None, None, 1, 2, None, -1, 2, 3]
Explanation: After `get(1)` and `get(2)`, both keys have frequency 2. Key 1 became frequency-2 earlier, so it is the LRU among that frequency and gets evicted.
Input: (['LFUCache', 'put', 'get', 'put', 'get', 'get'], [[1], [-1, -10], [-1], [-2, -20], [-1], [-2]])
Expected Output: [None, None, -10, None, -1, -20]
Explanation: Negative keys and values are valid. With capacity 1, inserting key -2 evicts key -1.
Hints
- You need one structure to find a key's current value and frequency quickly, and another structure to find the least frequently used key quickly.
- Within each frequency bucket, you still need LRU behavior. Think about combining a hash map with an ordered structure per frequency.