leetcode之LRU实现

来源:互联网 发布:mix软件怎么拼图 编辑:程序博客网 时间:2024/06/05 02:23

题目:

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 


思路:

首先想到至少要维护两个数据结构,一个存key,value对本身(数据结构一),一个要记录访问记录排序,对第一个数据结构,由于需要快速查找,考虑用map存储,关于第二个数据结构,考虑两点,第一要顾及到排序,第二,要顾及到更新,因为有序是该数据结构的必然要求,而更新是该数据结构最常见的操作,基于这两点,考虑到用链表(数据结构二),但是链表有个问题,就是查找速度太慢,需要从头到尾扫描,这样的时间复杂度是肯定通不过leetcode OJ 的test case的,而在做更新的时候,是需要快速定位到某个节点的,所以要么把不用链表,换成其他数据结构,要么要再加一个数据结构以对链表进行记录,那么考虑用map吧(数据结构三)。有了这三个数据结构以后,考虑到数据结构二的更新操作涉及到节点移动,并需要记录最后一个节点(最近最少使用节点,这里把最近用过的节点都放在链表头部,最少使用的放在尾部,按最近访问顺序依次排序),设置一个类变量记录最后一个节点的地址,以减少搜索该节点的时间。


代码:

struct OrderNode{int key;OrderNode *next;OrderNode *prev;OrderNode(int x) : key(x), next(NULL), prev(NULL){};};class LRUCache{private:std::map<int, OrderNode*> orderfinder;  //find the previous node of the node in the order listOrderNode * orderlist;std::map<int, int> slot;int capacity;OrderNode * lastNode;public:LRUCache(int capacity) {this->capacity = capacity;orderlist = NULL;}int get(int key) {//not foundif (slot.find(key) == slot.end()) {return -1;}else  //found key{//record access for the node an update the access list;OrderNode* keyplace = orderfinder[key];//if the first nodeif (keyplace->prev == NULL){return slot[key];}keyplace->prev->next = keyplace->next;//if not lastNodeif (keyplace->next != NULL){keyplace->next->prev = keyplace->prev;}else{lastNode = lastNode->prev;lastNode->next = NULL;}keyplace->prev = NULL;keyplace->next = orderlist;orderlist->prev = keyplace;orderlist = keyplace;return slot[key];}}void set(int key, int value) {//initialization of empty orderlistif (orderlist == NULL){OrderNode *tmp = new OrderNode(key);orderlist = tmp;orderfinder.insert(std::pair<int, OrderNode*>(key, tmp));slot.insert(std::pair<int, int>(key, value));lastNode = tmp;}else if (slot.find(key) != slot.end()) //found the key already exist{//change the existing valueslot[key] = value;//update the orderlist by moving the node to firstOrderNode* keyplace = orderfinder[key];if (keyplace == orderlist)//already the in first place{return;}if (keyplace->next != NULL)// IF NOT THE LAST ELEMENT {keyplace->next->prev = keyplace->prev;}else{lastNode = keyplace->prev;}keyplace->prev->next = keyplace->next;keyplace->prev = NULL;keyplace->next = orderlist;orderlist->prev = keyplace;orderlist = keyplace;}else if ((int)slot.size()<capacity) //still has space to insert{//insert new nodeslot.insert(std::pair<int, int>(key, value));OrderNode* tmp = new OrderNode(key);tmp->next = orderlist;orderlist->prev = tmp;orderlist = tmp;orderfinder.insert(std::pair<int, OrderNode*>(key, tmp));}else //push the last node out of orderlist{//insert new nodeslot.insert(std::pair<int, int>(key, value));OrderNode* tmp = new OrderNode(key);if (capacity>1){tmp->next = orderlist;orderlist->prev = tmp;//update slot using delete element from mapslot.erase(slot.find(lastNode->key));OrderNode* pre = lastNode->prev;orderfinder.erase(orderfinder.find(lastNode->key));//update lastNode after pushing outlastNode = pre;lastNode->next = NULL;}else{tmp->next = NULL;slot.erase(slot.find(lastNode->key));orderfinder[lastNode->key] = tmp;OrderNode * p = orderlist;delete p;lastNode = tmp;}orderlist = tmp;orderfinder.insert(std::pair<int, OrderNode*>(key, tmp));}}};


0 0
原创粉丝点击