Implement an LRU cache
Reference
Frontier Interview's solution
Endorsed
Start your answer
Remix this answer and make it yours, or start blank. Either way you work beside the reference, one chapter at a time, and it stays private until you publish it.
Problem statement
Implement a least-recently-used cache with get(key) and put(key, value), both in O(1) time, with a fixed capacity.
Approach
Keep a hash map from key to node, and a doubly linked list ordered by recency (most recent at the head). get moves the node to the head; put inserts at the head and evicts from the tail when over capacity. Both are O(1).
Sentinel head and tail nodes remove the empty-list edge cases.
Code
class Node:
__slots__ = ("key", "value", "prev", "next")
def __init__(self, key=0, value=0):
self.key, self.value = key, value
self.prev = self.next = None
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.map = {}
self.head, self.tail = Node(), Node()
self.head.next, self.tail.prev = self.tail, self.head
def _remove(self, node):
node.prev.next, node.next.prev = node.next, node.prev
def _push_front(self, node):
node.prev, node.next = self.head, self.head.next
self.head.next.prev = node
self.head.next = node
def get(self, key: int) -> int:
node = self.map.get(key)
if not node:
return -1
self._remove(node)
self._push_front(node)
return node.value
def put(self, key: int, value: int) -> None:
if key in self.map:
self._remove(self.map[key])
node = Node(key, value)
self.map[key] = node
self._push_front(node)
if len(self.map) > self.capacity:
lru = self.tail.prev
self._remove(lru)
del self.map[lru.key]
Complexity
-
getandput: O(1) time. - Space: O(capacity).
Test cases
| Operations | Expected |
|---|---|
| cap 2: put(1,1), put(2,2), get(1), put(3,3), get(2) | 1, then -1 (2 was evicted) |
| cap 1: put(1,1), put(1,2), get(1) | 2 (update, no eviction) |
| cap 2: get(5) on empty cache | -1 |
Follow-ups interviewers ask: make it thread-safe (a lock around both operations, or striped locks), add TTL expiry, or use OrderedDict.move_to_end in Python.