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);
 */

 

posted @ 2019-05-20 22:47  Joel_Wang  阅读(298)  评论(0编辑  收藏  举报