双向链表LRU 缓存
class Solution {
list<pair<int, int>> mCache;
int mCapacity;
public:
Solution(int capacity):mCapacity(capacity){
// write code here
}
int get(int key) {
// write code here
auto iter=mCache.begin();
for(;iter!=mCache.end();++iter){
if(iter->first==key){
break;
}
}
if (iter==mCache.end()) return -1;
auto temp = *iter;
mCache.erase(iter);
mCache.emplace_front(temp);
return temp.second;
}
void set(int key, int value){
// write code here
auto iter=mCache.begin();
for(;iter!=mCache.end();++iter){
if(iter->first==key){
break;
}
}
if (iter!=mCache.end()) mCache.erase(iter);
if(mCache.size()==mCapacity){
auto iter = --mCache.end();
mCache.erase(iter);
}
mCache.emplace_front(make_pair(key, value));
}
};
本实现存在的问题:
链表对于键的查找开销相当大,因为比起连续地址的数组和 vector类型,链表在访问的时候多一个指针的递归,在底层上内存访问也可能回慢一点;
待优化部分
于是利用 哈希表来对键值查询的过程做优化 也即是优化如下代码块:
auto iter=mCache.begin();
for(;iter!=mCache.end();++iter){
if(iter->first==key){
break;
}
}
哈希表 双向链表 LRU 缓存
整体代码如下:
class Solution {
list<pair<int, int>> mCache;
unordered_map<int, list<pair<int,int>>::iterator> mp;
int mCapacity;
public:
Solution(int capacity):mCapacity(capacity){
// write code here
}
int get(int key) {
// write code here
if(mp.find(key)!=mp.end()){
int value = mp[key]->second;
mCache.erase(mp[key]);
mCache.emplace_front(make_pair(key, value));
mp[key] = mCache.begin();
return value;
}else return -1;
}
void set(int key, int value){
// write code here
if(mp.find(key)!=mp.end()) // 链表中存在键删除后重新插入;
mCache.erase(mp[key]);
else if(mCache.size()==mCapacity){ // 不存在键同时链表满容量;
mp.erase(mCache.back().first);
mCache.pop_back();
}
// 插入键值对到表头;
mCache.emplace_front(make_pair(key, value));
mp[key] = mCache.begin();
}
};
优化性能
可以看出结果很好;其实第二种方法做的时候没想到,是我看评论区被别人的方法启发的做出来的;