//双链表节点
struct dListNode{ dListNode* pre; dListNode* next; int key; int value; dListNode(int k = 0, int v = 0) :key(k), value(v), pre(NULL), next(NULL){} }; class LRUCache { public: LRUCache(int capacity):_size(capacity) { head = new dListNode(); tail = new dListNode(); head->next = tail; tail->pre = head; } void removeNode(dListNode* node) { node->pre->next = node->next; node->next->pre = node->pre; //delete node; } void aJustNodeToHead(dListNode* newNode) { //新节点头插 head->next->pre = newNode; newNode->next = head->next; head->next = newNode; newNode->pre = head; //map关联到链表 //_map.insert(make_pair(key, newNode)); } int get(int key) { auto iter = _map.find(key); if (iter != _map.end()) { //存在,先删除再头插 dListNode* node = iter->second; int targetNum = node->value; //_map.erase(key); removeNode(node); aJustNodeToHead(node); return targetNum; } return -1; } void put(int key, int value) { auto iter = _map.find(key); if (iter != _map.end()) { //存在,先删除再头插 dListNode* node = iter->second; //值变化 node->value = value; removeNode(node); aJustNodeToHead(node); } else { //不存在 if (_map.size() == _size) { //满了得先删除尾部,再头插 _map.erase(tail->pre->key); auto iter = tail->pre; removeNode(tail->pre); delete iter; } dListNode* newNode = new dListNode(key, value); aJustNodeToHead(newNode); _map.insert(make_pair(key, newNode)); } } private: dListNode* head; dListNode* tail; unordered_map<int, dListNode*> _map; int _size; };
leetcode上的题目,使用最优的时间复杂度,用hashmap保存指向双链表的指针实现查找O(1),而双链表的删除也是O(1),put和get元素都是O(1),hashmap+双链表的方法真的神,一开始自己用vector和list虽然也实现了功能,但是数据就惨很多,原因是list的查找是O(n)的,还需要定义一个指定大小的vector,着实扣脚,下边给出这个版本供参考:
class LRUCache { public: LRUCache(int capacity):_size(capacity) { //扩容到足够大 _vec.resize(3001); } int get(int key) { if(_vec[key]==0)return -1; int target =-1; for(auto iter=_list.begin();iter!=_list.end();++iter) { if(iter->first==key) { target=iter->second; _list.erase(iter); _list.push_back(make_pair(key,target)); break; } } return target; } void put(int key, int value) { //存在先删除 if(_vec[key]>0) { for(auto iter = _list.begin();iter!=_list.end();++iter) { if(iter->first==key) { _list.erase(iter); break; } } } if(_list.size()==_size) { //满了,说明不存在,直接删除头 auto top=_list.front(); --_vec[top.first]; _list.pop_front(); } _list.push_back(pair<int,int>(key,value)); ++_vec[key]; } private: list<pair<int,int>> _list; //记录每个key是否存在 vector<int> _vec; //链表最大长度 int _size; };