146. LRU Cache (List, HashTable)
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.
思路:Hashmap+double-linked list.
Hashmap: key是已给的key,value是ListNode的地址
double-linked list:当链表中某元素要被删除或提到head时,双向链表都方便进行操作
class LRUCache{ private: /*double-linked list*/ struct ListNode{ ListNode * prev; ListNode * next; int key; int value; ListNode(int _key, int _value):key(_key), value(_value), prev(NULL), next(NULL){} }; /*move the node to the head of liest*/ void change2TopPriority(ListNode* listNode){ if(head==listNode) return; //special case: it's the head listNode->prev->next = listNode->next; if(listNode->next) listNode->next->prev = listNode->prev; else tail = tail->prev; //special case: it's the tail listNode->prev = NULL; listNode->next = head; head->prev = listNode; head = head->prev; } public: LRUCache(int capacity) { listNodeMap.clear(); this->capacity = capacity; head = NULL; tail = NULL; } int get(int key) { if(listNodeMap.find(key)!=listNodeMap.end()){ change2TopPriority(listNodeMap[key]); return listNodeMap[key]->value; } else return -1; } void set(int key, int value) { if(listNodeMap.find(key)==listNodeMap.end()){ // ket not exist if(listNodeMap.size()==capacity){ // reach the capacity //erase least used data listNodeMap.erase(tail->key); ListNode * tmp = tail; if(head == tail) { //special case: capacity=1 head = tail = NULL; } else{ tail = tail->prev; tail->next = NULL; } delete tmp; } //insert new node ListNode * newNode = new ListNode(key,value); if(!head){ //special case: first node in the list head = tail = newNode; } else{ head->prev = newNode; newNode->next = head; head = head->prev; } listNodeMap[key]=newNode; } else{ //key already exists listNodeMap[key]->value = value; change2TopPriority(listNodeMap[key]); } } private: unordered_map<int,ListNode*> listNodeMap; //hashmap ListNode* head; //head of double linked list ListNode* tail; //tail of double linked list int capacity; //capacity of CRU };