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.
思路:使用哈希表来记录key与值。为了实现LRU,我们需要实现一个双向链表,最少使用的在链表头,最近使用的在链表尾。对于每一个key,我们还需要一个哈希表来记录它在该链表中的地址。
在代码实现过程中,新申请一个链表只能用new的形式来申请,该语句将返回一个申请后的指针。
1 class LRUCache{ 2 public: 3 class dlist 4 { 5 public: 6 dlist *pre, *next; 7 int key; 8 dlist(int d, dlist *p, dlist *f) : key(d), pre(p), next(f){} 9 }; 10 int cap; 11 dlist *front, *tail; 12 unordered_map<int, int> data; 13 unordered_map<int, dlist *> addr; 14 LRUCache(int capacity) { 15 cap = capacity; 16 front = new dlist(0, NULL, NULL); 17 tail = new dlist(0, NULL, NULL); 18 front->next = tail; 19 tail->pre = front; 20 } 21 22 int get(int key) { 23 if (data.count(key) == 0) return -1; 24 Delete(addr[key]); 25 AddtoTail(addr[key]); 26 return data[key]; 27 } 28 void AddtoTail(dlist *node) 29 { 30 tail->pre->next = node; 31 node->pre = tail->pre; 32 node->next = tail; 33 tail->pre = node; 34 } 35 void Delete(dlist *node) 36 { 37 node->pre->next = node->next; 38 node->next->pre = node->pre; 39 } 40 void set(int key, int value) { 41 if (data.size() == cap && data.count(key) == 0) 42 { 43 if (front->next == tail) return; 44 data.erase(front->next->key); 45 addr.erase(front->next->key); 46 Delete(front->next); 47 } 48 if (data.count(key) == 0) 49 { 50 data.insert(make_pair(key, value)); 51 dlist *ent = new dlist(key, NULL, NULL); 52 addr.insert(make_pair(key, ent)); 53 AddtoTail(ent); 54 } 55 else 56 { 57 data[key] = value; 58 Delete(addr[key]); 59 AddtoTail(addr[key]); 60 } 61 } 62 };