LRU 缓存(哈希表+双向链表)
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现
LRUCache 类:LRUCache(int capacity)以 正整数 作为容量capacity初始化 LRU 缓存int get(int key)如果关键字key存在于缓存中,则返回关键字的值,否则返回-1。void put(int key, int value)如果关键字key已经存在,则变更其数据值value;如果不存在,则向缓存中插入该组key-value。如果插入操作导致关键字数量超过capacity,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
示例:
输入
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]
解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4
struct DLinkedNode{ //变量 int key,value; DLinkedNode* pre; DLinkedNode* next; //构造方法 DLinkedNode(){ this->key = 0; this->value =0; this->pre = nullptr; this->next = nullptr; } DLinkedNode(int _key,int _value){ this->key = _key; this->value = _value; this->pre = nullptr; this->next = nullptr; } }; class LRUCache { private: map<int,DLinkedNode*> cache; //键值与节点的映射 int size; //链表实际长度 int capacity;//链表容量 DLinkedNode *head;//伪头结点 DLinkedNode *tail;//伪尾节点 public: LRUCache(int capacity) { this->size = 0; this->capacity = capacity; head = new DLinkedNode(); tail = new DLinkedNode(); head->next = tail; tail->pre = head; } int get(int key) { if(!cache.count(key)){ return -1; }else{//如果存在,放到头部,因为它是最近被访问的 DLinkedNode* node = cache[key]; moveToHead(node); return node->value; } } void put(int key, int value) { if(!cache.count(key)){//如果不存在,插入头部,并放进cache DLinkedNode* node = new DLinkedNode(key,value); cache[key] = node; addToHead(node); ++size; //如果超过容量,要删除末尾节点,因为它是最近最久未访问 if(size>capacity){ DLinkedNode* node = removeTail(); cache.erase(node->key); delete node; --size; } }else{//如果存在,更新value并放到头部,因为它是最近被访问的 DLinkedNode* node = cache[key]; node->value = value; moveToHead(node); } } void moveToHead(DLinkedNode* node){ removeNode(node); addToHead(node); } void removeNode(DLinkedNode* node){ node->next->pre = node ->pre; node->pre->next = node->next; } void addToHead(DLinkedNode* node){ head->next->pre=node; node->next = head->next; head->next = node; node->pre = head; } DLinkedNode* removeTail(){ DLinkedNode* node = tail->pre; removeNode(node); return node; } }; /** * Your LRUCache object will be instantiated and called as such: * LRUCache* obj = new LRUCache(capacity); * int param_1 = obj->get(key); * obj->put(key,value); */
浙公网安备 33010602011771号