Process Get and Set Operations in a Key-Value Cache
BalyasnySoftware Engineer · OnsiteLast updated
This problem tests your ability to implement an efficient, thread-safe, and memory-constrained LRU (Least Recently Used) cache using a combination of a hash map and a doubly linked list.
LRU Cache Implementation
Design and implement a data structure for an LRU (Least Recently Used) cache. The cache should support get(key) and put(key, value) operations with the following requirements:
get(key): Returns the value of thekeyif it exists, otherwise returns -1.put(key, value): Updates the value of thekeyif it exists. Otherwise, adds thekey-valuepair to the cache. If the cache reaches its capacity, it should invalidate the least recently used item before inserting a new item.
Implement the class LRUCache:
class LRUCache:
def __init__(self, capacity: int):
# Initialize the cache with a positive size capacity
pass
def get(self, key: int) -> int:
# Return the value of the key if the key exists, otherwise -1
pass
def put(self, key: int, value: int) -> None:
# Update the value of the key if it exists, otherwise add the pair
pass
Constraints
1 <= capacity <= 100,0000 <= key <= 1,000,0000 <= value <= 1,000,000,000- Operations should run in
O(1)average time complexity.
Examples
lru = LRUCache(2)
lru.put(1, 1) # Cache is {1=1}
lru.put(2, 2) # Cache is {1=1, 2=2}
lru.get(1) # Returns 1, Cache is {2=2, 1=1}
lru.put(3, 3) # Evicts key 2, Cache is {1=1, 3=3}
lru.get(2) # Returns -1 (not found)
Hints
Hint 1
Use a hash map to store keys mapped to nodes in a doubly linked list to achieve O(1) access and removal.
Hint 2
The doubly linked list should maintain the order of use: move the accessed or newly added node to the head, and remove from the tail when capacity is exceeded.
Hint 3
Ensure you update both the hash map and the linked list pointers consistently whenever a 'get' or 'put' operation occurs.
Follow-up questions
- How would you modify this implementation to be thread-safe in a multi-threaded environment?
- If keys are accessed with different frequencies, would an LRU cache still be the most effective strategy, or would an LFU (Least Frequently Used) cache be better?
- How would you handle cache persistence if the system needs to recover from a process crash?
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.