LRU cache
Implement LRUCache(capacity) with get(key), which returns the value or -1, and put(key, value). When the cache is full, adding a new key evicts the least recently used one. Both operations should be O(1).
c = LRUCache(2)
c.put(1, "a")
c.put(2, "b")
c.get(1) # "a" (1 is now most recent)
c.put(3, "c") # evicts 2
c.get(2) # -1
Show hint
You need fast lookup by key and a fast way to move a key to the "most recent" end. collections.OrderedDict has move_to_end and popitem(last=False).
Show solution
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity):
self.capacity = capacity
self.data = OrderedDict()
def get(self, key):
if key not in self.data:
return -1
self.data.move_to_end(key)
return self.data[key]
def put(self, key, value):
if key in self.data:
self.data.move_to_end(key)
self.data[key] = value
if len(self.data) > self.capacity:
self.data.popitem(last=False)
The OrderedDict keeps keys from least to most recently used. Reading or writing a key moves it to the end, and eviction removes from the front. Underneath, this is a hash map combined with a doubly linked list, which is exactly what interviewers often ask you to build by hand. Browser caches and CPU caches use the same policy.
Want a problem like this every day? See today's problem and keep a streak going.