146. LRU Cache
The concept is about double linked list.
k1, k2, k3.... k10 -> k1, k2, k4, ..... k10, k3 -> k2 , k4 , k5 .... k10 , k3 , k11
Custom double linked list
class Node:
def __init__(self, val):
self.val = val
self.pre = None
self.nxt = None
class LRUCache:
def __init__(self, capacity: int):
self.M = defaultdict(int)
self.cache = {}
self.capacity = capacity
self.head = Node(-1)
self.tail = Node(-1)
self.head.nxt = self.tail
self.tail.pre = self.head
def _remove(self, node):
pre, nxt = node.pre, node.nxt
pre.nxt, nxt.pre = nxt, pre
# node.pre.nxt, node.nxt.pre = node.nxt, node.pre
def get(self, key: int) -> int:
if key not in self.M:
return -1
node = self.cache[key]
self._remove(node)
# put it to tail
node.nxt = self.tail
node.pre = self.tail.pre
node.nxt.pre = node
node.pre.nxt = node
return self.M[key]
def put(self, key: int, value: int) -> None:
if key not in self.M:
node = Node(key)
self.cache[key] = node
else:
node = self.cache[key]
self._remove(node)
self.M[key] = value
# put it to tail
node.nxt = self.tail
node.pre = self.tail.pre
node.nxt.pre = node
node.pre.nxt = node
if len(self.M.keys()) > self.capacity:
node = self.head.nxt
self._remove(node)
del self.M[node.val]
del self.cache[node.val]
Use built-in function, see cheat sheet
class LRUCache:
def __init__(self, capacity: int):
self.od = OrderedDict()
self.capacity = capacity
def get(self, key: int) -> int:
if key not in self.od:
return -1
self.od.move_to_end(key)
return self.od[key]
def put(self, key: int, value: int) -> None:
if key in self.od:
self.od.move_to_end(key)
elif len(self.od) == self.capacity:
self.od.popitem(last=False)
self.od[key] = value