原题链接:LRU 缓存
个人解法
思路:
用双向链表维护LRU中的key和value,若访问到则将对应的结点置换到链表尾部,若需要替换则直接替换链表头部,这个比较难debug,要注意细节。
时间复杂度: O ( 1 ) O(1) O(1)
代码:
class LRUCache {
public:
struct Node {
int key, value;
Node *next;
Node *prev;
};
Node *head;
Node *tail;
int capacity;
unordered_map<int, Node *> mp;
LRUCache(int capacity) {
this->head = new Node();
this->head->next = nullptr;
this->head->prev = nullptr;
this->tail = head;
this->capacity = capacity;
}
void add(int key, int value) {
tail->next = new Node();
Node *t = tail;
tail = tail->next;
tail->key = key, tail->value = value, tail->prev = t;
tail->next = nullptr;
mp[key] = tail;
}
void update(int key) {
if(mp.count(key)) {
Node *p = mp[key];
if(p == tail) return;
p->prev->next = p->next;
p->next->prev = p->prev;
tail->next = p;
p->prev = tail;
tail = tail->next;
tail->next = nullptr;
}
}
int get(int key) {
update(key);
if(mp.count(key)) return mp[key]->value;
return -1;
}
void put(int key, int value) {
update(key);
if(mp.count(key)) mp[key]->value = value;
else if(capacity) {
add(key, value);
-- capacity;
}else {
add(key,value);
Node *t = head;
head = head->next;
mp.erase(head->key);
delete t;
}
}
};
/**
* 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);
*/