思路
双向链表+哈希表实现,要明白STL里的<map>是红黑树实现的,亲测速度不够,要用真.哈希表:<unordered_map>
可能有人要问,为啥不用单向链表?我的理解是为了删除元素的时候不用从头搜索。
当然,针对这道题是可以用单向链表的,即“删除”最无用节点的时候,对链表不作处理,而只是从哈希表里把值删掉。反正在搜索的时候也是直接查的哈希表。副作用是这个链表会越来越长。
另外,不想自己实现双向链表的话,可以用<list>
代码
struct LinkedNode{ int key; LinkedNode* next; LinkedNode* prev; LinkedNode(int _key = -1){ key = _key; next = NULL; prev = NULL; } }; class LRUCache{ private: LinkedNode* pHeader; LinkedNode* pEnd; unordered_map<int, int> keyValueMap; int cap; public: LRUCache(int capacity) { cap = capacity; pHeader = new LinkedNode(); //dummy node pEnd = new LinkedNode(); pHeader->next = pEnd; pEnd->prev = pHeader; } void refreshQueue(int key){ LinkedNode* pNode = pHeader; while(pNode->next != NULL){ if(pNode->next->key == key) break; pNode = pNode->next; } //Move pNode->next to head LinkedNode* pPrevNode = pNode; LinkedNode* pHitNode = pNode->next; LinkedNode* pNextNode = pHitNode->next; pPrevNode->next = pNextNode; pNextNode->prev = pPrevNode; pHeader->next->prev = pHitNode; pHitNode->prev = pHeader; pHitNode->next = pHeader->next; pHeader->next = pHitNode; } int removeLast(){ //Remove the last item and return its key LinkedNode* pToRemove = pEnd->prev; int key = pToRemove->key; LinkedNode* pPrev = pToRemove->prev; pPrev->next = pEnd; pEnd->prev = pPrev; delete pToRemove; return key; } int get(int key) { if(keyValueMap.count(key) > 0){ //Change priority queue refreshQueue(key); //Get value return keyValueMap[key]; } else { return -1; } } void insert(int key){ LinkedNode* pNext = pHeader->next; LinkedNode* pNewNode = new LinkedNode(key); pNewNode->next = pNext; pNewNode->prev = pHeader; pHeader->next = pNewNode; pNext->prev = pNewNode; } void set(int key, int value) { if(keyValueMap.count(key)){ keyValueMap[key] = value; //set key //Refresh queue refreshQueue(key); } else { if(keyValueMap.size() == cap){ int oldKey = removeLast(); keyValueMap.erase(oldKey); } keyValueMap[key] = value; insert(key); } } };