题解 | #LFU缓存结构设计#

LFU缓存结构设计

http://www.nowcoder.com/practice/93aacb4a887b46d897b00823f30bfea1

class Solution {
private:
    typedef list<vector<int> > vecList; //定义元素为向量的双向链表,向量里为[频次,键,值]
    unordered_map<int, vecList> freq_map; //建立频次到双向链表的哈希表
    unordered_map<int, vecList::iterator> key_map;
    //建立键到双向链表迭代器的哈希表(迭代器可以简单理解为在双向链表中的指针类,通过它可以得到里面的元素)
    int least = 0; //记录当前最小频次
    int K;
    void refresh_key(vecList::iterator vlist, int key, int value) { //更新和加入新key都会刷新
        int num = (*vlist)[0]; //这里迭代器解引用(类似指针)取下标得到频次
        freq_map[num].erase(vlist); //在该频次下的双向链表中擦除迭代器指向位置中的元素
        if(freq_map[num].empty()) { //如果双向链表被擦空了
            freq_map.erase(num); //删除该频次的映射
            if(least == num) least++; //如果当前频次为最小频次,最小频次加一
        }
        freq_map[num + 1].push_front({num + 1, key, value});
        //插入频次加一的双向链表表头(若无此映射会自动创建空双向链表)
        key_map[key] = freq_map[num + 1].begin(); //更新键到双向链表迭代器的映射
    }
    void set(int key, int value) {
        auto it = key_map.find(key);
        if(it != key_map.end())
            refresh_key(it->second, key, value);
        else {
            if(K == 0) {
                int old_key = freq_map[least].back()[1];
                freq_map[least].pop_back();
                if(freq_map[least].empty())
                    freq_map.erase(least);
                key_map.erase(old_key);
            }
            else
                K--;
            least = 1;
            freq_map[1].push_front({1, key, value});
            key_map[key] = freq_map[1].begin();
        }
    }
    int get(int key) {
        auto it = key_map.find(key);
        if(it != key_map.end()) {
            auto vList_it = it->second;
            int value = (*vList_it)[2];
            refresh_key(vList_it, key, value);
            return value;
        }
        else
            return -1;
    }
public:
    /**
     * lfu design
     * @param operators int整型vector<vector<>> ops
     * @param k int整型 the k
     * @return int整型vector
     */
    vector<int> LFU(vector<vector<int> >& operators, int k) {
        // write code here
        K = k;
        vector<int> res;
        for(auto vec:operators) {
            if(vec[0] == 1)
                set(vec[1], vec[2]);
            else
                res.push_back(get(vec[1]));
        }
        return res;
    }
};
全部评论

相关推荐

嵐jlu:我是山川🐔里🐔🧱的,阿里系简历全过; 你这简历一看就还是半成品啊,没有荣誉经历奖项什么的吗?
投递阿里巴巴集团等公司10个岗位
点赞 评论 收藏
分享
叶扰云倾:进度更新,现在阿里云面完3面了,感觉3面答得还行,基本都答上了,自己熟悉的地方也说的比较细致,但感觉面试官有点心不在焉不知道是不是不想要我了,求阿里收留,我直接秒到岗当阿里孝子,学校那边的房子都退租了,下学期都不回学校,全职猛猛实习半年。这种条件还不诱人吗难道 然后现在约到了字节的一面和淘天的复活赛,外加猿辅导。华为笔试完没动静。 美团那边之前投了个base广州的,把我流程卡麻了,应该是不怎么招人,我直接简历挂了,现在进了一个正常的后端流程,还在筛选,不知道还有没有hc。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务