146. LRU 缓存
题目链接:146. LRU 缓存
代码如下:
cpp
//哈希表+双链表
//参考leetcode官方题解
//LRU:最近最少使用算法,将新插入的或刚修改或使用的放到表头,表尾即为最不常使用的
class DLinkedLNode//双链表的定义
{
public:
int m_key,m_val;
DLinkedLNode *pre,*next;
DLinkedLNode():m_key(0),m_val(0),pre(nullptr),next(nullptr){}
DLinkedLNode(int key,int value):m_key(key),m_val(value),pre(nullptr),next(nullptr){}
};
class LRUCache {
public:
LRUCache(int capacity) {
m_capacity=capacity;
size=0;
//建立头结点+尾节点
head=new DLinkedLNode();
tail=new DLinkedLNode();
//首尾相连
head->next=tail;
tail->pre=head;
}
int get(int key) {
if(cache.find(key)==cache.end())
return -1;
DLinkedLNode *node=cache[key];
moveToHead(node);
return node->m_val;
}
void put(int key, int value) {
//不存在就创建
if(cache.find(key)==cache.end())
{
DLinkedLNode *node=new DLinkedLNode(key,value);
addToHead(node);
cache[key]=node;
size++;
if(size>m_capacity)
{
cache.erase(removeTail());
size--;
}
}
else//存在就修改
{
DLinkedLNode* node=cache[key];
node->m_val=value;
moveToHead(node);
}
}
public:
unordered_map<int,DLinkedLNode*> cache;
int size;
int m_capacity;
DLinkedLNode *head;
DLinkedLNode *tail;
//把节点插入到链表头部
void addToHead(DLinkedLNode* node)
{
node->pre=head;
node->next=head->next;
head->next->pre=node;
head->next=node;
}
//把这个节点移出链表
void removeNode(DLinkedLNode* node)
{
node->pre->next=node->next;
node->next->pre=node->pre;
}
void moveToHead(DLinkedLNode* node)
{
removeNode(node);
addToHead(node);
}
//返回值为key,便于查找和删除cache中保存的键值对
int removeTail()
{
DLinkedLNode* node=tail->pre;
removeNode(node);
int key=node->m_key;
delete node;
return key;
}
};
/**
* 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);
*/