Leetcode146.LRU cache(最近最少使用)

题目:
设计和实现最近最少使用(LRU)缓存的数据结构。它应支持以下操作:get和put。
get(key)-如果键在缓存中,则获取键的值(始终为正),否则返回-1。
put(key, value)-如果密钥不存在,请设置或插入值。当缓存达到其容量时,它应在插入新项目之前使最近最少使用的项目无效。
高速缓存初始化为正容量。
思路:
需要实现一个类。首先两个任务:1,使用易于查找O(1)的数据结构来存key-value,使用无序map;2,需要知道每次的put和get时的最近最少使用的节点是哪一个。然后在map的size==capacity时,踢掉不需要的来插入需要的。使用list来满足O(1)的时间复杂度来查找到map的key的迭代器
细节说明:
采用了unordered_map的结构,key和pair来组合。这样组合的意义在于更加方便的通过map的 iterator 来耦合list,来修改和查询list的位置。

实现:
注意是整个缓存都要改变。

class LRUCache {
private:
    typedef list<int> LNode;
    typedef pair<int,LNode::iterator> Pair;     //pair中保存的才是val
    typedef unordered_map<int, Pair> MyMap;
    
    //每一个LRUcached 都有一个map用于 索引; 一个list用于管理 最近缓存
    MyMap cache;        //hash
    LNode Recent;       //list
    
    int _capacity;      
    
    void moveNode(MyMap::iterator it){
        
        int key=it->first;      //键值
        Recent.erase(it->second.second);        //节点已经被删除了,迭代器失效了!需要再赋值
        Recent.push_front(key);
        it->second.second=Recent.begin();       //key对应的节点迭代器赋值
    };
public:
    LRUCache(int capacity):_capacity(capacity) {}
    
    int get(int key) {
    if(cache.find(key)!=cache.end()){
        //说明找到了
        auto it=cache.find(key);
        moveNode(it);
        return it->second.first;
        }
    else 
        return -1;
    }
    
    void put(int key, int value) {
        if(cache.find(key)==cache.end()){
            //cache没有
            if(Recent.size()==_capacity){
                cache.erase(Recent.back());
                Recent.pop_back();
            }
            Recent.push_front(key);     //再首部
        }
        else
            moveNode(cache.find(key));      //有,移动就可
        //避免同一个键回改变val
        cache[key]={value, Recent.begin()};
        return ;
    }
};

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

后一篇文章补充unordered_map。

the stones you collect will become the way you walk.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值