赞
踩
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRU是Least Recently Used的缩写,意为“最近最少使用”。LRU是一种常用的缓存淘汰策略,用于管理缓存中的数据。
举个例子,你从一堆书中找出自己想要看的书,读完之后一般是放在最上面;如果你又从其他地方拿了一本书读完之后,打算放入这堆书中,如果这堆书中还有同名书,只是年份不同,那么就用这本书进行替换,如果没有同名书,由于“空间”不够使用,只能将最底下的书移走,再放入这本书
LRU缓存算法的基本思想是:当缓存空间不足时,优先淘汰最近最少使用的数据,以便为新数据腾出空间。具体来说,LRU算法会维护一个有序列表,列表中的元素按照访问时间从新到旧排列。每当缓存命中时,就将命中的数据移动到列表的头部,每当缓存缺失时,就将新数据插入到列表的头部,并将列表尾部的数据淘汰掉。
LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。
如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
由于题目要求O(1)复杂度,采取双链表,每个节点都是一本书;使用哈希来快速查找书籍
先创建节点Node
struct Node{
int _key;
int _value;
Node* _next;
Node* _prev;
Node(int key, int value): _key(key), _value(value), _next(nullptr), _prev(nullptr){}
};
刚开始时,使用一个哨兵节点
class LRUCache {
private:
Node* _dummy;
int _capacity;
unordered_map<int, Node*> _map;
public:
LRUCache(): _dummy(new Node(-1, -1)), _capacity(0){
_dummy->_next = _dummy;
_dummy->_prev = _dummy;
}
};
实现查找书
Node* get_node(int key)//查找书
{
auto it=_map.find(key);
if(it==_map.end())//没找到
return nullptr;
auto node=it->second;//找到了
remove(node);//从书堆中取出
insert_to_head(node);//放在书顶
return node;
}
实现将书从书堆中移除
void remove(Node* node)//从书堆中移除
{
node->_prev->_next = node->_next;
node->_next->_prev = node->_prev;
}
实现将书放入书顶
void insert_to_head(Node* node)//放入书顶
{
node->_next = _dummy->_next;
node->_prev = _dummy;
_dummy->_next->_prev = node;
_dummy->_next = node;
}
实现取书get功能
int get(int key)
{
auto node=get_node(key);//查找这本书
return node?node->_value:-1;
}
实现放入put功能
void put(int key, int value) { auto node = get_node(key); if(node)//书堆中已经存在,进行替换 { node->_value=value; return; } _map[key]=node=new Node(key, value); insert_to_head(node);//独一份,放入书顶 if(_map.size()>_capacity) { auto node=_dummy->_prev; remove(node); _map.erase(node->_key); delete node; } }
完整代码
struct Node{ int _key; int _value; Node* _next; Node* _prev; Node(int key, int value): _key(key), _value(value), _next(nullptr), _prev(nullptr){} }; class LRUCache { private: Node* _dummy; int _capacity; unordered_map<int, Node*> _map; void remove(Node* node)//从书堆中移除 { node->_prev->_next = node->_next; node->_next->_prev = node->_prev; } void insert_to_head(Node* node)//放入书顶 { node->_next = _dummy->_next; node->_prev = _dummy; _dummy->_next->_prev = node; _dummy->_next = node; } Node* get_node(int key)//查找书 { auto it=_map.find(key); if(it==_map.end())//没找到 return nullptr; auto node=it->second;//找到了 remove(node);//从书堆中取出 insert_to_head(node);//放在书顶 return node; } public: LRUCache(): _dummy(new Node(-1, -1)), _capacity(0){ _dummy->_next = _dummy; _dummy->_prev = _dummy; } int get(int key) { auto node=get_node(key);//查找这本书 return node?node->_value:-1; } void put(int key, int value) { auto node = get_node(key); if(node)//书堆中已经存在,进行替换 { node->_value=value; return; } _map[key]=node=new Node(key, value); insert_to_head(node);//独一份,放入书顶 if(_map.size()>_capacity) { auto node=_dummy->_prev; remove(node); _map.erase(node->_key); delete node; } } };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。