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