LRU作为页面置换算法和Redis内存淘汰策略,是很重要的一种算法,在面试中经常要求手写,下面使用list+unordered_map实现了LRU。
class LRUCache {
public:
int sz;
// list存储所有的key和value
list<pair<int, int>> lst;
// 存储每一个key在list中的结点位置(便于list删除结点)
unordered_map<int, list<pair<int, int>>::iterator> ump;
LRUCache(int capacity) {
sz = capacity;
}
int get(int key) {
// get的时候如果结点已存在,那么需要把结点移动到list头部
if (ump.find(key) != ump.end())
{
put(key, ump[key]->second);
return ump[key]->second;
}
else
return -1;
}
void put(int key, int value) {
// 如果key已经在list中了,先删除该节点
if (ump.find(key) != ump.end())
{
lst.erase(ump[key]);
}
// 如果list容量已满,则删除list尾部的结点
else if (lst.size() >= sz)
{
ump.erase(lst.back().first);
lst.pop_back();
}
// 把新的结点添加到list头部
lst.push_front({ key, value});
// 保存头结点到map中
ump[key] = lst.begin();
}
};
// test
LRUCache cache(2);
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // returns 1
cache.put(3, 3); // evicts key 2
cache.get(2); // returns -1 (not found)
cache.put(4, 4); // evicts key 1
cache.get(1); // returns -1 (not found)
cache.get(3); // returns 3
cache.get(4); // returns 4