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.
LRU是虚拟内存技术中,页置换时需要用到的算法,最近最少使用算法。也就是说替换掉最近最少被使用的页。
采用双链表实现一个栈,栈顶(用head指针表示)放最近使用的元素。end指针表示栈底,地方不够的时候end指针的元素值就会被覆盖,覆盖后因为成了最近使用,所以会被提到head的位置。链表中部也可能有元素被提到head的位置。
class LRUCache{ struct ListNode{ int key; int value; ListNode* prev; ListNode* next; }; public: LRUCache(int capacity){ if(capacity >= 0){ Capacity = capacity; size = 0; } } void set(int key, int value){ ListNode* p = head; for(; p != NULL && p -> key != key; p = p -> next); if(p == NULL && size == Capacity){ //The case that didn't find key and capacity is full p = end; p -> key = key; } if(p != NULL){ //The case that has found the key (treat the previous case as found the key in end) p -> value = value; if(p != head){ //If the key is in head of the list, we don't need to do anything since the head is the most recently used. ListNode* pre = p -> prev; ListNode* fol = p -> next; if(p == end && pre != NULL){ end = pre; } p -> next = head; p -> prev = NULL; head -> prev = p; head = p; if(pre != NULL) pre -> next = fol; if(fol != NULL) fol -> prev = pre; } }else{ //The case that has not found the key, and capacity is not full, need to create one. p = new ListNode(); p -> key = key; p -> value = value; if(head == NULL){ head = end = p; p -> prev = NULL; p -> next = NULL; }else{ p -> prev = NULL; p -> next = head; head -> prev = p; head = p; } size++; } } int get(int key){ ListNode* p = head; for(; p != NULL && p -> key != key; p = p -> next); if(p == NULL) return -1; if(p != head){ ListNode* pre = p -> prev; ListNode* fol = p -> next; if(p == end) end = pre; p -> next = head; p -> prev = NULL; head -> prev = p; head = p; if(pre != NULL) pre -> next = fol; if(fol != NULL) fol -> prev = pre; } return p -> value; } private: ListNode* head = NULL; ListNode* end = NULL; int size = 0; int Capacity = 0; };