leetcode 146LRU cache
class LRUCache { public: LRUCache(int capacity) {_capacity=capacity;} //返回key对应的value int get(int key){ auto it=cache.find(key); if(it==cache.end()) return -1; update(it);//更改为最近访问 return it->second.first;//返回key值对应的value } void put(int key,int value){ auto it=cache.find(key); if(it!=cache.end()) update(it); else{ if(cache.size()==_capacity){ //删除缓存里最老的元素,cache和used中都删掉 cache.erase(used.back()); used.pop_back(); } used.push_front(key); } cache[key]={value,used.begin()}; } private: //表示used,使用链表来存储近期使用过的值 typedef list<int> LI; //pair类型,第一个元素为value,第二个元素为value的值的存储位置; typedef pair<int,LI::iterator> PII; //表示cache的key值和value的值和指针, typedef unordered_map<int,PII>HIPII; HIPII cache;//定义一个cache LI used;//定义一个最近访问的list(双端链表) int _capacity; //将对应的cache节点更改到最近访问的属性 void update(HIPII::iterator it){ int key=it->first; used.erase(it->second.second);//删除该元素,通过指针(迭代器),这也是保留LI::iterator的原因 used.push_front(key);//将该元素列为最新使用元素 //以指针指向的位置作为cache与used之间的联系; it->second.second=used.begin();//将最近使用的最新元素的位置存储到PII类型的第二个元素中 } };
一个更整齐的版本:
/****** //定义三个private数据,LRU尺寸,LRU pair<key,value>, LRU map<key,iterator of pair> //利用splice操作erase,makepair 等完成LRUcache //put() 如果m中有对应的key,value,那么移除l中的key,value 如果m中没有,而size又==cap,那么移除l最后一个key,value,并移除m中对应的key,iterator 在l的开头插入key,value,然后m[key]=l.begin(); ****/ class LRUCache { public: LRUCache(int capacity){ cap=capacity; } int get(int key){ unordered_map<int,list<pair<int,int>>::iterator>::iterator it=m.find(key); if(it==m.end()) return -1; l.splice(l.begin(),l,it->second); return it->second->second; } void put(int key,int value){ auto it=m.find(key); if(it!=m.end()) l.erase(it->second); if(l.size()==cap){ int k=l.rbegin()->first; l.pop_back(); m.erase(k);//map可以根据key值和迭代器值移除,查找 } l.push_front(make_pair(key,value)); m[key]=l.begin(); } private: int cap;//LRU size list<pair<int,int>>l;//pair<key,value> unordered_map<int,list<pair<int,int>>::iterator>m;//unordered_map<key,key&value's pair iterator> }; /** * Your LRUCache object will be instantiated and called as such: * LRUCache* obj = new LRUCache(capacity); * int param_1 = obj->get(key); * obj->put(key,value); */