LEETCODE 460 实现LFU缓存

25 篇文章 0 订阅
11 篇文章 0 订阅

leetcode 460
在这里插入图片描述
在这里插入图片描述
方法一:双哈希表法
题目要求需要在常数时间完成插入和查找算法,联系之前的LRU算法,很容易想到用哈希表。具体做法如下:
第一个哈希表存储 使用频率freq一个双向链表这样一对映射,链表的每个节点存储key valuefreq(使用频率);
第二个哈希表存储 freq链表中的一个节点这样一对映射;
1.对于get()操作
首先根据key找到对应的链表节点,从而在第二个哈希表中找到value,freq,同时将该节点从当前链表删除(如果删除后为空,可能需要更新最小freq).将freq+1,新建一个节点插入下一个链表中;
2.对于put()操作
如果key已经存在,那么等同于get()操作,只需要另外将value更新就可以;

否则,判断当前是否达到了最大容量限制,若没有则只需要新建一个节点{freq=1,key,value},更新两个哈希表和最小使用频率即可;若达到了最大最大容量,找到最小使用频率对应的节点,将其从两个哈希表中删除,同时可能需要更新最小使用频率;

class LFUCache {
  public:  
    struct node
    {
        int key,val,freq;
        node(int k,int v,int f):key(k),val(v),freq(f){}     
    };
    
    unordered_map<int,list<node>>cache;//以频率为索引
    unordered_map<int,list<node>::iterator>sea;//以键值为索引
    int sz;
    int minfreq;
public:
    LFUCache(int capacity) {
     sz=capacity;
     minfreq=0;
    }
    
    int get(int key) {
    if(sz==0||sea.find(key)==sea.end())return -1;
    auto it=sea[key];
    list<node>::iterator no=it;
    int f=no->freq,val=no->val;
    cache[f].erase(no);
    node n(key,val,f+1);
    cache[f+1].push_front(n);
    if(cache[f].size()==0)
    {
        cache.erase(f);
        if(minfreq==f)
            minfreq++;
    } 
    sea[key]=cache[f+1].begin();
    return val;
    }
    
    void put(int key, int value) {
    if(sz==0)return;
    if(sea.size()>0&&sea.find(key)!=sea.end())
    {
       get(key);
       sea[key]->val=value;   
     
    }
     else
    {
         
         if(sea.size()==sz)
         {
             auto no=cache[minfreq].back();
             int f=no.freq,val=no.val,k=no.key;
             
             cache[minfreq].pop_back();
             if(cache.count(minfreq)==0)
             {
                 minfreq+=1;
                 cache.erase(f);
             }
             sea.erase(k);         
         }
                 
        auto no=node(key,value,1);
        cache[1].push_front(no);
        minfreq=1;
        sea[key]=cache[1].begin();
    }
    }
   
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值