146. LRU Cache
Problem
First encountered: 2023/3/14-15:21
Approach
Simple simulation using a dictionary — I didn't actually use the doubly linked list or LRU concepts. I feel guilty about this one; I can barely remember the air conditioner I built six months ago.
The answer should be understandable from the code comments. Feel free to ask if anything is unclear.
Code
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.cache = collections.OrderedDict()
def get(self, key: int) -> int:
# if key is in the dictionary, return its value
if key in self.cache:
self.cache.move_to_end(key)
return self.cache[key]
else:
# if key is not in the dictionary, return -1
return -1
def put(self, key: int, value: int) -> None:
if key in self.cache:
# if key is in the dictionary, update its value
self.cache.move_to_end(key)
self.cache[key] = value
else:
if len(self.cache) == self.capacity:
# if key is not in the dictionary and cache is full, evict LRU element
self.cache.popitem(last=False)
# if key is not in the dictionary and cache is not full, add the element
self.cache[key] = valueSecond Solution
class Node:
# Speed up attribute access and save memory
__slots__ = 'prev', 'next', 'key', 'value'
def __init__(self, key=0, value=0):
self.key = key
self.value = value
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.dummy = Node() # sentinel node
self.dummy.prev = self.dummy
self.dummy.next = self.dummy
self.key_to_node = dict()
def get_node(self, key: int) -> Optional[Node]:
if key not in self.key_to_node: # key not found
return None
node = self.key_to_node[key] # key found
self.remove(node) # remove from current position
self.push_front(node) # move to front
return node
def get(self, key: int) -> int:
node = self.get_node(key)
return node.value if node else -1
def put(self, key: int, value: int) -> None:
node = self.get_node(key)
if node: # key exists
node.value = value # update value
return
self.key_to_node[key] = node = Node(key, value) # new node
self.push_front(node) # move to front
if len(self.key_to_node) > self.capacity: # over capacity
back_node = self.dummy.prev
del self.key_to_node[back_node.key]
self.remove(back_node) # remove LRU node
# Remove a node
def remove(self, x: Node) -> None:
x.prev.next = x.next
x.next.prev = x.prev
# Add a node at the front of the linked list
def push_front(self, x: Node) -> None:
x.prev = self.dummy
x.next = self.dummy.next
x.prev.next = x
x.next.prev = x贡献者
这篇文章有帮助吗?
最近更新
Involution Hell© 2026 byCommunityunderCC BY-NC-SA 4.0