# LRU 缓存机制
运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制

实现 LRUCache 类:

 

进阶:你是否可以在 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

 

提示:

以下错误的选项是?

## aop ### before ```cpp #include using namespace std; ``` ### after ```cpp ``` ## 答案 ```cpp class LRUCache { public: LRUCache(int capacity) : cap(capacity) {} int get(int key) { if (m.count(key) != 0) { int val = m[key]->second; l.erase(m[key]); l.push_front({key, val}); m[key] = l.begin(); return val; } return -1; } void put(int key, int value) { if (m.count(key) != 0) { l.erase(m[key]); l.push_front({key, value}); m[key] = l.begin(); } else { m.erase(l.back().first); l.pop_back(); l.push_front({key, value}); m[key] = l.begin(); } } private: int cap; list> l; unordered_map>::iterator> m; }; ``` ## 选项 ### A ```cpp class LRUCache { private: unordered_map 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)) { return -1; } DLinkedNode *node = cache[key]; moveToHead(node); return node->value; } void put(int key, int value) { if (!cache.count(key)) { DLinkedNode *node = new DLinkedNode(key, value); cache[key] = node; addToHead(node); ++size; if (size > capacity) { DLinkedNode *removed = removeTail(); cache.erase(removed->key); delete removed; --size; } } else { DLinkedNode *node = cache[key]; node->value = value; moveToHead(node); } } void addToHead(DLinkedNode *node) { node->prev = head; node->next = head->next; head->next->prev = node; head->next = node; } void removeNode(DLinkedNode *node) { node->prev->next = node->next; node->next->prev = node->prev; } void moveToHead(DLinkedNode *node) { removeNode(node); addToHead(node); } DLinkedNode *removeTail() { DLinkedNode *node = tail->prev; removeNode(node); return node; } }; ``` ### B ```cpp class LRUCache { private: int capacity; list> cl; unordered_map>::iterator> cm; public: LRUCache(int capacity) { this->capacity = capacity; } int get(int key) { auto it = cm.find(key); if (it != cm.end()) { pair p = *cm[key]; int value = p.second; cl.erase(cm[key]); cl.push_front(p); cm[key] = cl.begin(); return value; } else return -1; } void put(int key, int value) { auto it = cm.find(key); if (it != cm.end()) { cl.erase(cm[key]); cl.push_front({key, value}); cm[key] = cl.begin(); } else { if (cl.size() == capacity) { int old_key = cl.back().first; cl.pop_back(); cm.erase(old_key); } cl.push_front({key, value}); cm.insert({key, cl.begin()}); } } }; ``` ### C ```cpp class LRUCache { private: int capacity, size; list cl; unordered_map cm; public: LRUCache(int capacity) { this->capacity = capacity; size = 0; } int get(int key) { auto it = cm.find(key); if (it != cm.end()) { cl.remove(key); cl.push_back(key); return it->second; } else return -1; } void put(int key, int value) { auto it = cm.find(key); if (it != cm.end()) { it->second = value; cl.remove(key); cl.push_back(key); } else { if (size == capacity) { int old_key = cl.front(); cl.pop_front(); cm.erase(old_key); size--; } cl.push_back(key); cm.insert({key, value}); size++; } } }; ```