一、设计
设计 LRUCache 类:
- LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存。
- int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
- void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
二、实现
使用c++ stl中的双向链表list和map结合,list连接各个节点并通过key将节点的迭代器存放在map中。
- map:这里主要起到随机访问的作用
- list:这里起到连接节点之间的关系的作用,主要是更具get和put来改变节点的位置。
- 关键:
关键是结构的定义,这里list必须关联key用于删除要淘汰的节点对应的map元素。需要使用pair构建数据对**(key,value)**。
list<pair<int,int>> m_list;
map<int,list<pair<int,int>>::iterator> m_cacheMap;
class LRUCache {
public:
LRUCache(int capacity):
m_capacity(capacity)
{
}
int get(int key) {
auto iterMap = m_cacheMap.find(key);
int ret = -1;
//查表没有直接返回-1
if(iterMap == m_cacheMap.end()){
return ret;
}
ret = iterMap->second->second;
m_list.erase(iterMap->second);
m_list.push_front(make_pair(key, ret));
m_cacheMap[key] = m_list.begin();
return ret;
}
void put(int key, int value) {
auto iterMap = m_cacheMap.find(key);
//是否在缓存中
if(m_cacheMap.end() != iterMap){
m_list.erase(iterMap->second);
}
else{
//超出缓存大小则删除尾节点
if(m_cacheMap.size() >= m_capacity){
m_cacheMap.erase(m_list.back().first);
m_list.pop_back();
}
}
//加载数据到链表头节点
m_list.push_front(make_pair(key,value));
m_cacheMap[key] = m_list.begin();
}
private:
int m_capacity;
list<pair<int,int>> m_list;
map<int,list<pair<int,int>>::iterator> m_cacheMap;
};