Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get
and set
.
get(key)
- Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value)
- Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
1:构建数据结构,包含头尾节点的双向链表和unorder_map<int, doubleLinkList> 结构;2:消除最近最少使用的节点,当访问一个节点的时候,把被访问的节点放置在头节点的后面;当删除节点的时候,删除尾节点的前一个节点,并相应的对map结构进行处理。3:注意特殊情况
class LRUCache{
public:
LRUCache(int capacity)
{
size = capacity;
myMap.clear();
head = new doubleLinkList(-1, -1);
tail = new doubleLinkList(-1, -1);
head->next = tail;
tail->pre = head;
}
int get(int key)
{
unordered_map<int, doubleLinkList*>::iterator itr = myMap.find(key);
if(itr != myMap.end())
{
doubleLinkList *tmp = itr->second;
tmp->next->pre = tmp->pre;
tmp->pre->next = tmp->next;
putNodeTohead(tmp);
return tmp->value;
}
else
{
return -1;
}
}
void set(int key, int value)
{
unordered_map<int, doubleLinkList* >::iterator itr = myMap.find(key);
if(itr != myMap.end())
{
doubleLinkList* tmp = itr->second;
tmp->value = value;
tmp->next->pre = tmp->pre;
tmp->pre->next = tmp->next;
putNodeTohead(tmp);
return;
}
else
{
if(size > 0)
{
doubleLinkList* tmp = new doubleLinkList(key, value);
putNodeTohead(tmp);
size--;
myMap[key] = tmp;
return;
}
else
{
if(head->next == tail)
{
return;
}
else
{
doubleLinkList* delNode = tail->pre;
unordered_map<int, doubleLinkList* >::iterator itr = myMap.find(delNode->key);
myMap.erase(itr);
delNode->next->pre = delNode->pre;
delNode->pre->next = delNode->next;
delete delNode;
doubleLinkList* tmp = new doubleLinkList(key, value);
putNodeTohead(tmp);
myMap[key] = tmp;
return;
}
}
}
}
private:
struct doubleLinkList
{
int key;
int value;
doubleLinkList *pre;
doubleLinkList *next;
doubleLinkList(int x, int y) : key(x), value(y), pre(NULL), next(NULL){}
};
doubleLinkList* head;
doubleLinkList* tail;
int size;
unordered_map<int, doubleLinkList* > myMap;
void putNodeTohead(doubleLinkList* tmpNode)
{
head->next->pre = tmpNode;
tmpNode->pre = head;
tmpNode->next = head->next;
head->next = tmpNode;
}
};