LRU Cache [leetcode]

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.

set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

这题的关键是要选好数据结构,刚开始用链表保存key, 每当访问某个key时便将key移到链表首部,当容量满时移除链表的尾部元素。虽然链表的删除时间复杂度为O(1), 但是链表的查找时间却是O(L), 超时。

之后使用两个缓存表,并给每个key设一个id,每当访问一个key时,会将访问的key的id更新为当前的m_id,然后m_id自加1,其中一个缓存表tab1为:<key,<value,id>>, 另一个缓存表tab2为: <id,key>, 这样就可以根据给定的key获取key对应的value和id,然后再根据这个id来查找tab2中value为key项,删除该项,再插入(m_id,key), 插入时是根据id自动排好序的,因此每更新一个key项,该key项总会移到tab2的尾部, 这样容量满时,只需找到tab2的首部,移除掉就行了。

class LRUCache{
private:
    int m_id;  //key的id,id越大优先级越高,每当访问一个key,更新该key的id为m_id, 然后m_id++
    int m_capacity;   
    map<int,pair<int,int> > m_tab1;  //<key,<value,id> > >速查表,加个id是为了在m_tab2中找到id对应的关键字
    map<int,int> m_tab2;  //<id,key>,将关键字按id排序(LRU排序)
    
public:
    LRUCache(int capacity) {
        m_id = 0;
        m_capacity = capacity;
    }
    
    int get(int key) {
        if(m_tab1.find(key)!=m_tab1.end()){
            //更新关键字key的id
            pair<int,int> tmp = m_tab1[key];
            int key_id = tmp.second;  //key对应的id
           
            m_tab2.erase(key_id);  //移除旧的<id,key>
            m_tab2[m_id] = key;   //将key的id更新为m_id
            m_tab1[key] = make_pair(tmp.first,m_id);  //同时更新m_tab1中的<key,<value,id> >的id
            m_id++;  
            return tmp.first;
        }
        else return -1;
    }
    
    void set(int key, int value) {
        if(m_tab1.find(key)!=m_tab1.end()){
			int key_id = m_tab1[key].second;
            m_tab2.erase(key_id);   
        }
		else if(m_tab1.size()==m_capacity){
            m_tab1.erase((m_tab2.begin())->second); //移除掉id最小的key
            m_tab2.erase(m_tab2.begin());
        }
        
        m_tab1[key] = make_pair(value,m_id);
        m_tab2[m_id] = key;
        m_id++;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值