• 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);
     */
  • 相关阅读:
    2020.9.26
    2020.10.2
    判断方法
    sql与include
    File类的获取方法
    【每日日报】第十五天
    【每日日报】第十三天
    【每日日报】第十四天
    两数相加(输入框)
    判断闰年
  • 原文地址:https://www.cnblogs.com/joelwang/p/10897093.html
Copyright © 2020-2023  润新知