问题:
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.
用一个doubly linked list来保存数据。其中head后边一个是最新的;tail前面一个是最旧的;在用一个map来处理查找。注意,不论是查找、更改还是新添加,都应该造成被造作的节点被排在了第一个。
代码:
struct LN {
std::pair<int, int> val;
LN *prev;
LN *next;
LN (int a, int b) : val(std::make_pair(a, b)), prev(NULL), next(NULL) {}
};
class LRUCache{
int size;
int cap;
LN *head;
LN *tail;
map<int, LN*>lookUp;
public:
LRUCache(int capacity) {
size = 0;
cap = capacity;
head = new LN(-1, -1);
tail = new LN(-2, -1);
head->next = tail;
tail->next = head;
}
int get(int key) {
if (lookUp.find(key) == lookUp.end())
return -1;
else {
LN *toMove = lookUp[key];
LN *prev = toMove->prev;
LN *next = toMove->next;
prev->next = next;
next->prev = prev;
next = head->next;
toMove->next = next;
next->prev = toMove;
head->next = toMove;
toMove->prev = head;
return toMove->val.second;
}
}
void set(int key, int value) {
// in the table
if (lookUp.find(key) != lookUp.end()) {
LN *toMove = lookUp[key];
LN *prev = toMove->prev;
LN *next = toMove->next;
prev->next = next;
next->prev = prev;
next = head->next;
toMove->next = next;
next->prev = toMove;
head->next = toMove;
toMove->prev = head;
lookUp[key]->val.second = value;
return;
}
// not in the table
if (size == cap) { // if full
// delete the LRU
LN *prev = tail->prev->prev;
LN *toDelete = tail->prev;
lookUp.erase(toDelete->val.first);
prev->next = tail;
tail->prev = prev;
delete toDelete;
}
// add the new one
LN *temp = new LN(key, value);
LN *next = head->next;
temp->prev = head;
head->next = temp;
temp->next = next;
next->prev = temp;
lookUp[key] = temp;
if (size < cap) size ++;
return;
}
};