来源于陈C同学(CC)
来源于陈C同学(CC)
来源于陈C同学(CC)
11 LRU缓存
作者: Turbo时间限制: 1S章节: 课程设计
问题描述 :
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
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) 的平均时间复杂度运行。
示例:
输入
2
put 1 1
put 2 2
get 1
put 3 3
get 2
put 4 4
get 1
get 3
get 4
输出
1
-1
-1
3
4
解释
LRUCache lRUCache = new LRUCache(2);//容量为2,即最多只能保存两个关键字
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1。注意,这里使用了1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废(在关键字1和2中,2是最久未被使用的),缓存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4
输入说明 :
输入若干行:
第一行输入一个整数capacity表示LRU缓存的容量。
后面每行输入为put或get:
如果指令为put类型,后面需要输入两个整数表示key和value。
如果指令为get类型,后面需要输入一个整数表示key。
提示:
1 <= capacity <= 3000
0 <= key <= 10000
0 <= value <= 10^5
最多调用 2 * 10^5 次 get 和 put
输出说明 :
输出若干行:
每行一个整数,表示为get指令的返回值。
输入范例 :
#include<bits/stdc++.h>
using namespace std;
struct Node
{
int key;
int value;
Node *pre;
Node *next;
public:
Node(int key, int value, Node *pre=nullptr, Node *next=nullptr): key(key), value(value), pre(pre), next(next) {}
friend void insertNode(Node *postionNode, Node *node);
friend void RemoveNode(Node *node);
};
void insertNode(Node *postionNode, Node *node) // 将节点node插入curNode前面
{
node->pre = postionNode;
node->next = postionNode->next;
postionNode->next->pre = node;
postionNode->next = node;
}
void RemoveNode(Node *node)
{
node->pre->next = node->next; // 删除节点node
node->next->pre = node->pre;
}
class Lru
{
private:
int capability; // 容量
std::unordered_map<int,Node*> table; // 哈希链表
Node *head; // 链表虚拟头部
Node *tail; // 链表虚拟尾部
public:
Lru(int capability) : capability(capability)
{
head = new Node(0,0);
tail = new Node(0,0);
head->next = tail;
tail->pre = head;
}
int get(int key)
{
if(!table.count(key))
{
cout<<-1<<endl;
return -1;
}
Node *node = table[key];
RemoveNode(node);
insertNode(head, node);
cout<<node->value<<endl;
return node->value;
}
void put(int key, int value)
{
if(!table.count(key))
{
if(table.size() >= capability)
{
Node *node = tail->pre;
table.erase(node->key);
if(node != nullptr)
{
RemoveNode(node);
delete node;
}
}
Node *node = new Node(key,value);
table[key] = node;
insertNode(head, node);
}
else
{
Node *node = table[key];
node->value = value; // 更新value
RemoveNode(node);
insertNode(head, node);
}
}
};
int main()
{
int capacity;
cin>>capacity;
string str;
int key,value;
Lru lru(capacity);
while(cin>>str)
{
if(str=="put")
{
cin>>key>>value;
lru.put(key,value);
}
else
{ cin>>key;
lru.get(key);
}
}
return 0;
}