leetcode 460. LFU Cache

Posted ymjyqsx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 460. LFU Cache相关的知识,希望对你有一定的参考价值。

hash:存储的key、value、freq

freq:存储的freq、key,也就是说出现1次的所有key在一起,用list连接

 

class LFUCache {
public:
    LFUCache(int capacity) {
        cap = capacity;
    }
    
    int get(int key) {
        auto it = hash.find(key);
        if(it == hash.end())
            return -1;                              这段代码以下处理的都是已有key的情况

        freq[hash[key].second].erase(iter[key]);    如果这个key已经有了,那次数就要加1。所以必须把freq里面的对应次数的key先删除,然后更新hash里key对应的次数,
        ++hash[key].second;                         同时在freq中将这个key连接次数加1的地方
        freq[hash[key].second].push_back(key);
        iter[key] = --freq[hash[key].second].end(); 因为这个key在freq中变换了位置,那对应的迭代器地址也应该改变,是push_back进去的,所以尾地址-1就好了
        if(freq[min_freq].size() == 0)              代码走到这一步,一定是有key存在的。如果min_freq没有了值,证明就是
            ++min_freq;
        return hash[key].first;
    }
    
    void put(int key, int value) {
        if(cap <= 0)
            return;
        if(get(key) != -1){                          注意调用的是 get(key),不是find
            hash[key].first = value;                 如果这个key已经存在,就不用考虑容量的问题,直接更新value就好了,因为不用新添加
            return;
        }
        if(hash.size() >= cap){
            hash.erase(freq[min_freq].front());      删除出现次数最少的中最久未出现的,list中越新出现的从后push进去
            iter.erase(freq[min_freq].front());      为什么要删除迭代器???
            freq[min_freq].pop_front();
        }
        hash[key] = {value,1};                       对出现一次的key进行添加
        freq[1].push_back(key);
        iter[key] = --freq[1].end();
        min_freq = 1;
    }
    int cap,min_freq;
    unordered_map<int,pair<int,int>> hash;
    unordered_map<int,list<int>> freq;
    unordered_map<int,list<int>::iterator> iter;
};

 https://www.cnblogs.com/grandyang/p/6258459.html

以上是关于leetcode 460. LFU Cache的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 460. LFU Cache

[LeetCode] 460. LFU Cache 最近最不常用页面置换缓存器

460. LFU缓存

460. LFU Cache

460. LFU Cache

leetcode 460 LFU缓存