题目大意:设计数据结构实现LRU缓存机制,使得页面访问和置换的时间复杂度均为O(1)。
分析:哈希表+双向链表。哈希表查找O(1),双向链表插入/删除O(1),满足题意要求。
双向链表的每个结点为一个页面pair<key,value>,队首为最新访问过的页面,队尾则为“最近最少”访问的页面,所以当页面数量到达缓存容量时,删去尾结点即可。
代码:转载自https://leetcode-cn.com/problems/lru-cache/solution/lru-cshi-xian-by-bao-bao-ke-guai-liao/
class LRUCache {
public:
LRUCache(int capacity) : capacity_(capacity) {}
int get(int key) {
if (hash.find(key) == hash.end())
return -1;
else {
int value = hash[key]->second;
doubly_linked_list.erase(hash[key]); //删除hash[key]指针指向的结点
doubly_linked_list.push_front(make_pair(key, value)); //访问=>页面放队首
hash[key] = doubly_linked_list.begin();
return value;
}
}
void put(int key, int value) {
if (hash.find(key) != hash.end()) //往已有页面中写数据
doubly_linked_list.erase(hash[key]); //先把已有页面的访问记录删掉
else if (doubly_linked_list.size() >= capacity_) { //超过容量
hash.erase(doubly_linked_list.back().first);
doubly_linked_list.pop_back(); //删除队尾(最近最少使用的)
}
doubly_linked_list.push_front(make_pair(key, value));
hash[key] = doubly_linked_list.begin();
}
private:
int capacity_;
list<pair<int, int>> doubly_linked_list; //双向链表结点:pair<key,value>
unordered_map<int, list<pair<int, int>>::iterator> hash;
};
/**
* 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);
*/