该题解采用哈希表和双向链表实现了一个 LRU 缓存机制。哈希表用于存储每个节点的引用,以便快速定位节点并在 O(1) 时间内完成删除或更新。双向链表用于按照访问的顺序存储节点,使得最近访问的节点总是移动到链表末尾,而最久未访问的节点位于链表头部。当缓存容量满时,链表头部的节点(即最久未访问的节点)被删除。
时间复杂度: O(1)
空间复杂度: O(capacity)
class Node:
def __init__(self, key, val):
self.key = key # 节点存储键
self.val = val # 节点存储值
self.next = None # 指向下一个节点
self.prev = None # 指向上一个节点
class DoubleList:
def __init__(self):
self.head = Node(0, 0) # 初始化头结点
self.tail = Node(0, 0) # 初始化尾节点
self.head.next = self.tail
self.tail.prev = self.head
self.size = 0 # 链表大小
def remove(self, node):
node.prev.next = node.next
node.next.prev = node.prev
self.size -= 1 # 删除节点时减少链表大小
def remove_first(self):
if self.head.next == self.tail:
return
first = self.head.next
self.remove(first)
return first # 返回被删除的第一个节点
def add_last(self, node):
node.prev = self.tail.prev
node.next = self.tail
node.prev.next = node
self.tail.prev = node
self.size += 1 # 添加节点时增加链表大小
class LRUCache:
def __init__(self, capacity: int):
self.map = dict() # 哈希表存储键到节点的映射
self.cache = DoubleList() # 双向链表存储节点
self.capacity = capacity
def get(self, key: int) -> int:
if key not in self.map:
return -1 # 如果键不存在,返回-1
self.make_recent(key)
return self.map[key].val # 返回键对应的值
def put(self, key: int, value: int) -> None:
if key in self.map:
self.delete_key(key)
self.add_recent(key, value)
return
if self.capacity == len(self.map):
self.remove_least_recent() # 移除最久未使用的节点
self.add_recent(key, value) # 添加最新的节点
def make_recent(self, key):
node = self.map[key]
self.cache.remove(node)
self.cache.add_last(node) # 将节点移动至链表末尾
def add_recent(self, key, val):
node = Node(key, val)
self.cache.add_last(node)
self.map[key] = node # 在哈希表中更新或添加键与节点的映射
def delete_key(self, key):
node = self.map[key]
self.cache.remove(node)
del self.map[key] # 从哈希表中删除键
def remove_least_recent(self):
node = self.cache.remove_first()
del self.map[node.key] # 删除最少使用的节点
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)