Design a Recency-Eviction Cache
PinduoduoSoftware Engineer · Technical ScreenLast updated
This problem tests your ability to implement a Least Recently Used (LRU) cache using a combination of a hash map and a doubly linked list to achieve constant time operations.
Problem Statement
Design and implement a data structure for a Least Recently Used (LRU) cache. The cache should have a fixed capacity n and support the following operations:
get(key): Returns the value of thekeyif it exists in the cache, otherwise return -1. If the key is accessed, it must be marked as the most recently used item.put(key, value): Updates the value of thekeyif it exists. Otherwise, add thekey-valuepair to the cache. If the cache reaches its capacity before adding the new item, it must remove the least recently used item.
Your implementation must ensure that both get and put operations run in average O(1) time complexity.
Interface
class LRUCache:
def __init__(self, capacity: int):
# Initialize cache with fixed capacity
pass
def get(self, key: int) -> int:
# Return value or -1
pass
def put(self, key: int, value: int) -> None:
# Add or update key-value pair
pass
Examples
Example 1:
Input: ["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
Output: [null, null, null, 1, null, -1, null, -1, 3, 4]
Explanation:
put(1, 1),put(2, 2): Cache is{1: 1, 2: 2}.get(1): Returns 1, cache becomes{2: 2, 1: 1}(1 is now most recent).put(3, 3): Cache full, evicts 2. Cache is{1: 1, 3: 3}.get(2): Returns -1 (not found).put(4, 4): Cache full, evicts 1. Cache is{3: 3, 4: 4}.
Constraints
capacitywill be between 1 and 100,000.keyandvaluewill be non-negative integers.- Total operations will not exceed 200,000.
Hints
Hint 1
To achieve O(1) access time, use a Hash Map to store keys mapped to their locations in the structure.
Hint 2
To maintain recency order and perform O(1) removals and additions, use a Doubly Linked List where the head is the most recent and the tail is the least recent.
Hint 3
When a key is accessed or updated, move its corresponding node to the head of the linked list.
Follow-up questions
- How would you modify this design to be thread-safe in a multi-threaded environment?
- What changes are needed if you want to implement a 'Least Frequently Used' (LFU) cache instead of LRU?
- How does the performance of your implementation change if the cache size is extremely large (e.g., millions of items) and memory becomes a constraint?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.