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.
struct Node
{
int key;
int val;
Node *prev;
Node *next;
Node(int k, int v) : key(k), val(v), prev(NULL), next(NULL)
{}
};
class LRUCache{
public:
LRUCache(int capacity) {
capa = capacity;
head = new Node(0, 0);
tail = new Node(0, 0);
head->next = tail;
tail->prev = head;
}
~LRUCache()
{
for (map<int, Node*>::iterator it = m.begin(); it != m.end(); it++)
{
delete it->second;
}
delete head;
delete tail;
}
int get(int key) {
if (m.find(key) == m.end())
{
return -1;
}
Node *p = m[key];
update(p);
return p->val;
}
void set(int key, int value) {
if (m.find(key) != m.end())
{
Node *p = m[key];
p->val = value;
update(p);
}
else
{
if (m.size() >= capa)
{
Node *p = tail->prev;
p->prev->next = tail;
tail->prev = p->prev;
m.erase(p->key);
delete p;
}
Node *p = new Node(key, value);
m[key] = p;
p->next = head->next;
head->next->prev = p;
head->next = p;
p->prev = head;
}
}
void update(Node *p)
{
p->next->prev = p->prev;
p->prev->next = p->next;
p->next = head->next;
head->next->prev = p;
p->prev = head;
head->next = p;
}
private:
map<int, Node*> m;
int capa;
Node *head;
Node *tail;
};