import collections
class LRUCache(collections.OrderedDict):
def __init__(self, capacity: int):
# super(LRUCache,self)首先找到 LRUCache 的父类(就是类 OrderedDict),然后把类 LRUCache 的对象转换为类 OrderedDict 的对象
super(LRUCache,self).__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)
#双向链表按照被使用的顺序存储了这些键值对,靠近头部的键值对是最近使用的,而靠近尾部的键值对是最久未使用的。
#哈希表即为普通的哈希映射(HashMap),通过缓存数据的键映射到其在双向链表中的位置。
class DLinkedNode:
def __init__(self,key=0,value=0) :
self.key=key
self.value=value
self.prev = None
self.next = None
class LRUCache:
def __init__(self, capacity: int):
self.cache = dict()
self.head = DLinkedNode()
self.tail = DLinkedNode()
self.head.next=self.tail
self.tail.prev=self.head
self.capacity=capacity
self.size=0
def get(self, key: int) -> int:
if key not in self.cache:
return -1
node = self.cache[key] #通过哈希表定位
self.moveToHead(node)
return node.value
def put(self, key: int, value: int) -> None:
if key not in self.cache:
node=DLinkedNode(key,value)
self.cache[key]=node #添加至哈希表 key:node
self.addToHead(node)
self.size+=1
if self.size>self.capacity:
removed = self.removeTail()
self.cache.pop(removed.key)
self.size-=1
else:
node=self.cache[key]
node.value=value
self.moveToHead(node)
def addToHead(self ,node:DLinkedNode):
node.prev=self.head
node.next=self.head.next
self.head.next.prev =node
self.head.next=node
def removeNode(self ,node:DLinkedNode):
node.prev.next=node.next
node.next.prev=node.prev
def moveToHead(self,node):
self.removeNode(node)
self.addToHead(node)
def removeTail(self) -> DLinkedNode:
node=self.tail.prev
self.removeNode(node)
return node
C++
struct DLinkedNode{
int key;
int value;
DLinkedNode*prev=NULL;
DLinkedNode*next=NULL;
DLinkedNode():key(0),value(0){}
DLinkedNode(int _key,int _value):key(_key),value(_value){}
};
class LRUCache {
private:
unordered_map<int,DLinkedNode*> cache;
DLinkedNode*head;
DLinkedNode*tail;
int size;
int capacity;
public:
LRUCache(int _capacity) {
capacity=_capacity;
size=0;
//使用伪头部和伪尾部
head=new DLinkedNode();
tail=new DLinkedNode();
head->next=tail;
tail->prev=head;
}
int get(int key) {
if(cache.count(key)==0)
return -1;
DLinkedNode*node=cache[key];
moveToHead(node);
return node->value;
}
void put(int key, int value) {
if(cache.count(key)==0){
DLinkedNode*node=new DLinkedNode(key,value);
cache[key]=node;
addToHead(node);
size++;
if(size>capacity){
DLinkedNode*removed=removeTial();
cache.erase(removed->key);
delete removed; //防止内存泄漏
--size;
}
}
else{
DLinkedNode*node=cache[key];
node->value=value;
moveToHead(node);
}
}
void moveToHead(DLinkedNode*node){
removeNode(node);
addToHead(node);
}
void removeNode(DLinkedNode*node){
node->prev->next=node->next;
node->next->prev=node->prev;
}
void addToHead(DLinkedNode*node){
node->next=head->next;
node->prev=head;
head->next->prev=node;
head->next=node;
}
DLinkedNode* removeTial(){
DLinkedNode*node=tail->prev;
removeNode(node);
return node;
}
};