LRU Cache
Medium
Subject: Design
Time Complexity
O(1)
Space Complexity
O(C)
Problem Description
Problem Statement
Design a data structure that follows the constraints of a Least Recently Used (LRU) cache. Implement the LRUCache class with get(key) and put(key, value) in O(1) average time complexity.
Example 1:
- Input:
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]\n[[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]
Optimal Solution
PythonApproach: Doubly Linked List + Hash Map
We use a hash map to store keys mapped to nodes in a custom doubly linked list. The DLL allows us to move recently accessed nodes to the front (head) in O(1) time. When capacity is exceeded, we remove the node at the tail (least recently used).
class DLLNode:
def __init__(self, key=0, val=0):
self.key = key
self.val = val
self.prev = None
self.next = None
class LRUCache:
def __init__(self, capacity: int):
self.cap = capacity
self.cache = {}
self.head = DLLNode()
self.tail = DLLNode()
self.head.next = self.tail
self.tail.prev = self.head
def _remove(self, node):
node.prev.next = node.next
node.next.prev = node.prev
def _add(self, node):
node.next = self.head.next
node.prev = self.head
self.head.next.prev = node
self.head.next = node
def get(self, key: int) -> int:
if key in self.cache:
node = self.cache[key]
self._remove(node)
self._add(node)
return node.val
return -1
def put(self, key: int, value: int) -> None:
if key in self.cache:
self._remove(self.cache[key])
node = DLLNode(key, value)
self.cache[key] = node
self._add(node)
if len(self.cache) > self.cap:
lru = self.tail.prev
self._remove(lru)
del self.cache[lru.key]