146. LRU 缓存
- 单向链表不遍历无法直接删除给定的节点
双向链表因为:哈希表给出待操作的节点指针,需要delete或者moveToHead操作,单向链表无法获取该node的前向节点,删除该节点 - 链表节点需要key是因为:deleteTail之后,需要把哈希表中对应的key也给删了
class CachedNode {
public:
int key, value;
CachedNode * prev = NULL, * next = NULL;
CachedNode():key(0), value(0){}
CachedNode(int k, int v):key(k), value(v){}
};
class LRUCache {
private:
int size = 0, cap;
map<int, CachedNode*> cachedNodeMap;
CachedNode * head, * tail;
public:
LRUCache(int capacity) {
cap = capacity;
head = new CachedNode();
tail = new CachedNode();
head->next = tail;
tail->prev = head;
}
int get(int key) {
if (cachedNodeMap.count(key) == 0) return -1;
int val = cachedNodeMap[key]->value;
moveToHead(cachedNodeMap[key]);
return val;
}
void put(int key, int value) {
if (cachedNodeMap.count(key) > 0) {
moveToHead(cachedNodeMap[key]);
cachedNodeMap[key]->value = value;
return;
}
CachedNode * newCachedNode = new CachedNode(key, value);
addToHead(newCachedNode);
cachedNodeMap[key] = newCachedNode;
size++;
if (size > cap) {
cachedNodeMap.erase(tail->prev->key);
deleteTail();
size--;
}
}
void moveToHead(CachedNode * node) {
node->prev->next = node->next;
node->next->prev = node->prev;
addToHead(node);
}
void addToHead(CachedNode * node) {
head->next->prev = node;
node->next = head->next;
head->next = node;
node->prev = head;
}
void deleteTail() {
CachedNode * deleteNode = tail->prev;
tail->prev = tail->prev->prev;
tail->prev->next = tail;
delete deleteNode;
}
};