设计可以变更的缓存结构(LRU)
描述
设计一种缓存结构,该结构在构造时确定大小,假设大小为k,并有两个功能:
set(key, value):将记录(key, value)插入该结构
get(key):返回key对应的value值
要求:
1.set和get方法的时间复杂度为O(1)。
2.某个key的set或者get操作一旦发生,认为这个key的记录成了最经常使用的
3.当缓存的大小超过k时,移除最不经常使用的记录。
实现
class LRUCache {
public:
//cache的大小
int size;
//把cache实现成一个双向链表
list<pair<int, int>> cache;
//用一个哈希来实现对双向链表任一元素的随机访问,即可实现O(1)
unordered_map<int, list<pair<int, int>>::iterator> map;
LRUCache(int capacity) {
this->size = capacity;
}
int get(int key) {
//判断key是否在cache中,如果不在,return -1
if(map.find(key) == map.end())
return -1;
//在cache中,移动到头部
pair<int, int> kv = *map[key];
cache.erase(map[key]);
cache.push_front(kv);
//更新哈希表
map[key] = cache.begin();
return kv.second;
}
void put(int key, int value) {
//判断key是否存在
if(map.find(key) == map.end())//不存在
{
//判断cache是否满了
if(cache.size() == size)//满了,删除尾部元素,再插到头部
{
//注意,cache和map都要删
auto last = cache.back();
int lastKey = last.first;
map.erase(lastKey);
cache.pop_back();
}
//插入
cache.push_front(make_pair(key, value));
map[key] = cache.begin();
}
else
{
//key存在,更新value值,再插入到头部
cache.erase(map[key]);
cache.push_front(make_pair(key, value));
map[key] = cache.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);
*/