力扣146. LRU 缓存(STL实现)

核心思路是有两个数据结构,一个哈希表和一个双向链表。双向链表用来实现一个队列,队头元素最近被使用,队尾元素最久没被使用;哈希表用来记录key与key相应的节点在链表中的指针。
1.面试场景要的应该是自己写结构体来实现双向链表,写的时候注意位置交换时指针的操作顺序
2.注意每次操作要同时维护哈希表和链表
3.STL中的list已经是双端队列,可以前插后插,也可以插在中间
4.list中需要存储key的值,方便通过list队尾元素来删除哈希表中相应的键值对
class LRUCache { public: list<pair<int, int>> deque; //这里不能直接使用deque,因为deque使用erase(it)会导致it之后的迭代器也失效 unordered_map<int, list<pair<int, int>>::iterator> table; int capacity; LRUCache(int capacity) { this -> capacity = capacity; } int get(int key) { auto it = table.find(key); if (it == table.end()) return -1; int v = it -> second -> second; deque.erase(it -> second); deque.push_front(make_pair(key, v)); table[key] = deque.begin(); return v; } void put(int key, int value) { auto it = table.find(key); if (it == table.end() && deque.size() == capacity) { //容量不够时删除队尾元素 table.erase(deque.back().first); //需要在哈希表中也删除队尾元素项 deque.pop_back(); } else if (it != table.end()){ deque.erase(it -> second); } deque.push_front(make_pair(key, value)); table[key] = deque.begin(); } }; /** * 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); */
使用list的splice函数快速移动迭代器到头部
1 class LRUCache { 2 public: 3 int capacity; 4 typedef pair<int, int> pii; 5 list<pii> cache; 6 unordered_map<int, list<pii>::iterator> m; 7 LRUCache(int capacity) { 8 this -> capacity = capacity; 9 } 10 11 int get(int key) { 12 if (m.count(key)) { 13 int value = m[key] -> second; 14 cache.splice(cache.begin(), cache, m[key]); 15 return value; 16 } 17 return -1; 18 } 19 20 void put(int key, int value) { 21 if (m.count(key)) { 22 m[key] -> second = value; 23 cache.splice(cache.begin(), cache, m[key]); 24 } else { 25 if (cache.size() == capacity) { 26 m.erase(cache.back().first); 27 cache.pop_back(); 28 cache.push_front(make_pair(key, value)); 29 m[key] = cache.begin(); 30 } else { 31 cache.push_front(make_pair(key, value)); 32 m[key] = cache.begin(); 33 } 34 } 35 } 36 }; 37 38 /** 39 * Your LRUCache object will be instantiated and called as such: 40 * LRUCache* obj = new LRUCache(capacity); 41 * int param_1 = obj->get(key); 42 * obj->put(key,value); 43 */
浙公网安备 33010602011771号