题解 | #设计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);
        }
    }
};

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务