LeetCode链接
手动实现双向链表 + dict 时间复杂度 get put O(1)
class Node:
def __init__(self, k=0, v=0):
self.k = k
self.v = v
self.next = None
self.prev = None
class LRUCache:
def __init__(self, capacity: int):
self.data = {}
self.capacity = capacity
self.size = 0
self.head = Node()
self.tail = Node()
self.head.next = self.tail
self.tail.prev = self.head
def get(self, key: int) -> int:
if key in self.data:
n = self.data[key]
self._remove(n)
self._add(n)
return n.v
return -1
def put(self, key: int, value: int) -> None:
if key in self.data:
n = self.data[key]
n.v = value
self._remove(n)
self._add(n)
else:
n = Node(key, value)
self.data[key] = n
self._add(n)
self.size += 1
if self.size > self.capacity:
n_to_remove = self.head.next
self._remove(n_to_remove)
self.data.pop(n_to_remove.k)
def _remove(self, n: Node):
n_prev = n.prev
n_next = n.next
n_prev.next = n_next
n_next.prev = n_prev
def _add(self, n: Node):
"""
此处add始终在尾部添加 配合_remove可以把常用的节点移动到链表的尾部
自然,头部就是最不经常使用的节点,长度超限,删除之即可
"""
tail_prev = self.tail.prev
tail_prev.next = n
n.prev = tail_prev
n.next = self.tail
self.tail.prev = n
基于已有的 collections.OrderedDict
class LRUCache(collections.OrderedDict):
def __init__(self, capacity: int):
super().__init__()
self.capacity = capacity
def get(self, key: int) -> int:
if key not in self :
return -1
self.move_to_end(key)
return self[key]
def put(self, key: int, value: int) -> None:
if key in self:
self.move_to_end(key)
self[key] = value
if len(self) > self.capacity:
self.popitem(last=False)
|