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

设计LFU缓存结构

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


#include <unordered_map>
struct node{
    struct node* next;
    struct node* prio;
    int key;
    int val;
    int rate;
    node(int _key,int _val,int _rate):next(nullptr),prio(nullptr),key(_key),val(_val),rate(_rate){}
};

struct LinkList{
    struct node* front;
    struct node* rear;
    int size;
    LinkList(){
        front=new node(0,0,0);
        rear=new node(0,0,0);
        front->next=rear;
        rear->prio=front;
        size=0;
    }
};



class Solution{
private:
    /*哈希表+双向链表
    //哈希表1存储key-Node对应关系
    //哈希表2存储的是频率-双向链表
    //每次set,先看是否有该key,无,则直接创建节点并插入到哈希表二对应频率的头部,有则执行更新(修改节点value),
        然后频率+1,添加到对应频率的双向链表头部
    //每次get,修改频率,添加到对应频率的双向链表头部,以上操作都为O(1)时间复杂度
    */
    int rate,k;
    unordered_map<int,node*> hmap_1;
    unordered_map<int, LinkList*> hmap_2;
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
        rate=0,k=_k;
        vector<int> ans;
        for(auto&v:operators){
            if(v[0]==1){
                set(v[1],v[2]);
            }
            else{
                int value=get(v[1]);
                ans.emplace_back(value);
            }
        }
        return ans;
    }

    void adjust(int key,int value){
        node* _node=hmap_1[key];
        _node->val=value;
        //更新rate
        if(hmap_2[_node->rate]->size==1&&_node->rate==rate){
            rate=_node->rate+1;
        }
        //从hmap_2对应频率的链表中移除_node
        --hmap_2[_node->rate]->size;
        _node->prio->next=_node->next;
        _node->next->prio=_node->prio;
        ++_node->rate;
        int _rate=_node->rate;
        if(hmap_2.count(_rate)==0){
            LinkList* l=new LinkList();
            hmap_2[_rate]=l;
        }
        hmap_2[_rate]->front->next->prio=_node;
        _node->next=hmap_2[_rate]->front->next;
        _node->prio=hmap_2[_rate]->front;
        hmap_2[_rate]->front->next=_node;
        ++hmap_2[_rate]->size;
    }
    int get(int key){
        if(hmap_1.count(key)==0) return -1;
        adjust(key,hmap_1[key]->val);
        return hmap_1[key]->val;
    }

    void set(int key,int value){
        //没有该关键字
        if(hmap_1.count(key)==0){
            //存储已满
            if(hmap_1.size()==k&&hmap_2[rate]->size>0){
                //删除频率为rate的尾节点
                struct node* del=hmap_2[rate]->rear->prio;
                hmap_2[rate]->rear->prio=del->prio;
                del->prio=nullptr;
                del->next=nullptr;
                hmap_1.erase(del->key);
                delete del;
                hmap_2[rate]->size--;
            }
            //插入
            struct node* _node = new node(key,value,1);
            hmap_1[key]=_node;
            if(hmap_2.count(1)==0) {
                LinkList* l=new LinkList();
                hmap_2[1]=l;
            }
            hmap_2[1]->front->next->prio=_node;
            _node->next=hmap_2[1]->front->next;
            _node->prio=hmap_2[1]->front;
            hmap_2[1]->front->next=_node;
            ++hmap_2[1]->size;
            rate=1;
        }
        else{
            adjust(key,value);
        }
    }
};

全部评论

相关推荐

11-07 13:31
怀化学院 Java
勇敢牛牛不怕难:又疯一个
点赞 评论 收藏
分享
ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务