O
(
1
)
O(1)
O(1) 时间复杂度可以通过哈希表+双向链表来实现
哈希表存储 <key, node ptr>
,可以在
O
(
1
)
O(1)
O(1) 时间内找到对应key
值的节点。
双向链表节点内存储{key,value,prev,next}
四个属性。每个节点的插入、删除操作都可以在常数时间完成。
链表中有固定的head, tail
节点,最近访问的节点移动到tail
之前,最不常访问key
值对应的节点则位于head
之后。
因此,每次访问只需要改变节点的位置,完成常数时间的更新。
附上代码:
struct BiLinkNode{
int key, value;
BiLinkNode* prev;
BiLinkNode* next;
BiLinkNode(): key(0), value(0), prev(nullptr), next(nullptr) {}
BiLinkNode(int _key, int _value, BiLinkNode* _prev, BiLinkNode* _next): key(_key), value(_value), prev(_prev), next(_next) {}
BiLinkNode(int _key, int _value): key(_key), value(_value), prev(nullptr), next(nullptr) {}
};
class LRUCache {
map<int, BiLinkNode*> cache;
int capacity;
BiLinkNode* head = new BiLinkNode(-1,-1);
BiLinkNode* tail = new BiLinkNode(-1,-1);
public:
LRUCache(int capacity) {
this->capacity = capacity;
head->next = tail;
head->prev = head;
tail->prev = head;
tail->next = tail;
}
int get(int key) {
if(!cache.count(key)) return -1;
cache[key]->prev->next = cache[key]->next;
cache[key]->next->prev = cache[key]->prev;
cache[key]->next = tail;
cache[key]->prev = tail->prev;
tail->prev->next = cache[key];
tail->prev = cache[key];
return cache[key]->value;
}
void put(int key, int value) {
if(cache.count(key)) {
cache[key]->value = value;
cache[key]->next->prev = cache[key]->prev;
cache[key]->prev->next = cache[key]->next;
}
else{
if(capacity <= cache.size()){
int del = head->next->key;
cache[del]->next->prev = cache[del]->prev;
cache[del]->prev->next = cache[del]->next;
cache.erase(del);
}
cache[key] = new BiLinkNode(key, value);
}
cache[key]->prev = tail->prev;
cache[key]->next = tail;
tail->prev = cache[key];
cache[key]->prev->next = cache[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);
*/