这个题简直就是对所学数据结构的一个汇总应用啊,太绝了,涉及list、map、hashmap,对还包含front()、back()方法返回的是值,而begin()方法返回的是迭代器指针,真的是一绝。
不往本子上记了,就记在博客下吧
一共定义了三个数据结构。
一个哈希表存放当前key对应的节点位置
一个频率表,用map,因为要根据频率进行排序,存放的是当前频率下,都有哪些节点,这时候用双向链表实现。
一个哈希表,存放当前key-frequency。

class LFUCache {
public:
    int capacity;
    int count = 0;
    unordered_map<int,list<pair<int,int>>::iterator> location;//记录每个节点所在频率链表的位置
    map<int,list<pair<int,int>>> frequence;//记录每个频率下有几个节点
    unordered_map<int,int> hashmap;//key-frequence记录每个节点及对应的频率
    LFUCache(int capacity) {
        this->capacity = capacity;
    }

    int get(int key) {
        if(capacity == 0 || !hashmap.count(key)) return -1;
        int oldfq = hashmap[key];
        int val = (*location[key]).second;
        frequence[oldfq].erase(location[key]);
        if(frequence[oldfq].empty()){
            frequence.erase(oldfq);
        }
        hashmap[key]++;//当前节点的频率值+1
        frequence[oldfq + 1].emplace_front(make_pair(key,val));//在频率表中重新插入该节点
        location[key] = frequence[oldfq + 1].begin();//重新改该节点的位置赋值
        return val;
    }

    void put(int key, int value) {
        if(capacity <= 0) return;//防止出现无效的情况
        if(hashmap.find(key) != hashmap.end()){//如果原先已经插入过当前值,进行更新
            int oldfq = hashmap[key];
            //去对应频率链表下删除那个节点
            frequence[oldfq].erase(location[key]);
            if(frequence[oldfq].empty()){
                frequence.erase(oldfq);
            }
            hashmap[key]++;//当前key对应的频率要+1
            frequence[oldfq + 1].emplace_front(make_pair(key,value));//在当前频率下插入最新节点
            //更新位置信息
            location[key] = frequence[oldfq + 1].begin();
            return;
        }
        //如果当前节点满了
        if(count == capacity){
            auto fre = frequence.begin();//此时返回的是指针
            auto listp = fre->second.back();//对于list返回的是最后一个数字对,而不是迭代器指针
            int n = listp.first;
            hashmap.erase(n);//频率表删除当前节点
            location.erase(n);//位置表删除
            fre->second.pop_back();//当前链表中删除这个节点
            if(fre->second.empty()){
                frequence.erase(fre->first);
            }
            count--;
        }
        //插入新key-val
        hashmap[key] = 1;
        frequence[1].emplace_front(make_pair(key,value));
        location[key] = frequence[1].begin();//存放的是指针
        count++;
    }
};

/**
 * Your LFUCache object will be instantiated and called as such:
 * LFUCache* obj = new LFUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */