题目链接:https://leetcode-cn.com/problems/lru-cache/
题目如下:
struct doublelist{
int key,value;
doublelist* pre;
doublelist* next;
//要熟练下面两种构造函数初始化的写法
doublelist():key(0),value(0),pre(nullptr),next(nullptr){}
doublelist(int _key,int _value):key(_key),value(_value),pre(nullptr),next(nullptr){}
};
//使用双向列表,是为了将时间复杂度将为O(1)
//将一个节点移到双向链表的头部,分为,删除末尾节点,以及将节点插入到链表头节点处
class LRUCache {
public:
LRUCache(int _capacity):capacity(_capacity),size(0){
head=new doublelist();
tail=new doublelist();
head->next=tail;
tail->pre=head;//这里头和尾都是dummynode
}
int get(int key) {
if(cache.count(key)==0) return -1;
//若key存在,先通过哈希表定位,再移动到头部
doublelist* node=cache[key];
moveTohead(node);
return node->value;
}
void put(int key, int value) {
if(cache.count(key)==0){
doublelist* node=new doublelist(key,value);
cache[key]=node;
addTohead(node);
size++;
if(size>capacity){
doublelist* remove=removeTail();
cache.erase(remove->key);
delete remove;
size--;
}
}else{
doublelist* node=cache[key];
node->value=value;
moveTohead(node);
}
}
void addTohead(doublelist* node){
node->pre=head;
node->next=head->next;
head->next->pre=node;
head->next=node;
}
void removeNode(doublelist* node){
node->pre->next=node->next;
node->next->pre=node->pre;
}
void moveTohead(doublelist* node){
removeNode(node);
addTohead(node);
}
doublelist* removeTail(){
doublelist* node=tail->pre;
removeNode(node);
return node;
}
private:
unordered_map<int,doublelist*> cache;//仅用于定位,然后再双向链表上操作,且每个链表节点上存放两个元素
doublelist* head;
doublelist* tail;
int size;
int capacity;
};
/**
* 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);
*/