classNode:def__init__(self,key:int,value:int)->None:self.key=keyself.value=valueself.freq=1self.prev=Noneself.next=NoneclassDoublyLinkedList:def__init__(self)->None:self.head=Node(-1,-1)self.tail=Node(-1,-1)self.head.next=self.tailself.tail.prev=self.headdefadd_first(self,node:Node)->None:node.prev=self.headnode.next=self.head.nextself.head.next.prev=nodeself.head.next=nodedefremove(self,node:Node)->Node:node.next.prev=node.prevnode.prev.next=node.nextnode.next,node.prev=None,Nonereturnnodedefremove_last(self)->Node:returnself.remove(self.tail.prev)defis_empty(self)->bool:returnself.head.next==self.tailclassLFUCache:def__init__(self,capacity:int):self.capacity=capacityself.min_freq=0self.map=defaultdict(Node)self.freq_map=defaultdict(DoublyLinkedList)defget(self,key:int)->int:ifself.capacity==0orkeynotinself.map:return-1node=self.map[key]self.incr_freq(node)returnnode.valuedefput(self,key:int,value:int)->None:ifself.capacity==0:returnifkeyinself.map:node=self.map[key]node.value=valueself.incr_freq(node)returniflen(self.map)==self.capacity:ls=self.freq_map[self.min_freq]node=ls.remove_last()self.map.pop(node.key)node=Node(key,value)self.add_node(node)self.map[key]=nodeself.min_freq=1defincr_freq(self,node:Node)->None:freq=node.freqls=self.freq_map[freq]ls.remove(node)ifls.is_empty():self.freq_map.pop(freq)iffreq==self.min_freq:self.min_freq+=1node.freq+=1self.add_node(node)defadd_node(self,node:Node)->None:freq=node.freqls=self.freq_map[freq]ls.add_first(node)self.freq_map[freq]=ls# Your LFUCache object will be instantiated and called as such:# obj = LFUCache(capacity)# param_1 = obj.get(key)# obj.put(key,value)
classNode{public:intkey;intvalue;intfreq;Node*prev;Node*next;Node(intkey,intvalue){this->key=key;this->value=value;this->freq=1;this->prev=nullptr;this->next=nullptr;}};classDoublyLinkedList{public:Node*head;Node*tail;DoublyLinkedList(){this->head=newNode(-1,-1);this->tail=newNode(-1,-1);this->head->next=this->tail;this->tail->prev=this->head;}voidaddFirst(Node*node){node->prev=this->head;node->next=this->head->next;this->head->next->prev=node;this->head->next=node;}Node*remove(Node*node){node->next->prev=node->prev;node->prev->next=node->next;node->next=nullptr;node->prev=nullptr;returnnode;}Node*removeLast(){returnremove(this->tail->prev);}boolisEmpty(){returnthis->head->next==this->tail;}};classLFUCache{public:LFUCache(intcapacity){this->capacity=capacity;this->minFreq=0;}intget(intkey){if(capacity==0||map.find(key)==map.end()){return-1;}Node*node=map[key];incrFreq(node);returnnode->value;}voidput(intkey,intvalue){if(capacity==0){return;}if(map.find(key)!=map.end()){Node*node=map[key];node->value=value;incrFreq(node);return;}if(map.size()==capacity){DoublyLinkedList*list=freqMap[minFreq];Node*node=list->removeLast();map.erase(node->key);}Node*node=newNode(key,value);addNode(node);map[key]=node;minFreq=1;}private:intcapacity;intminFreq;unordered_map<int,Node*>map;unordered_map<int,DoublyLinkedList*>freqMap;voidincrFreq(Node*node){intfreq=node->freq;DoublyLinkedList*list=freqMap[freq];list->remove(node);if(list->isEmpty()){freqMap.erase(freq);if(freq==minFreq){minFreq++;}}node->freq++;addNode(node);}voidaddNode(Node*node){intfreq=node->freq;if(freqMap.find(freq)==freqMap.end()){freqMap[freq]=newDoublyLinkedList();}DoublyLinkedList*list=freqMap[freq];list->addFirst(node);freqMap[freq]=list;}};/** * 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); */
usestd::cell::RefCell;usestd::collections::HashMap;usestd::rc::Rc;structNode{key:i32,value:i32,freq:i32,prev:Option<Rc<RefCell<Node>>>,next:Option<Rc<RefCell<Node>>>,}implNode{fnnew(key:i32,value:i32)->Self{Self{key,value,freq:1,prev:None,next:None,}}}structLinkedList{head:Option<Rc<RefCell<Node>>>,tail:Option<Rc<RefCell<Node>>>,}implLinkedList{fnnew()->Self{Self{head:None,tail:None,}}fnpush_front(&mutself,node:&Rc<RefCell<Node>>){matchself.head.take(){Some(head)=>{head.borrow_mut().prev=Some(Rc::clone(node));node.borrow_mut().prev=None;node.borrow_mut().next=Some(head);self.head=Some(Rc::clone(node));}None=>{node.borrow_mut().prev=None;node.borrow_mut().next=None;self.head=Some(Rc::clone(node));self.tail=Some(Rc::clone(node));}};}fnremove(&mutself,node:&Rc<RefCell<Node>>){match(node.borrow().prev.as_ref(),node.borrow().next.as_ref()){(None,None)=>{self.head=None;self.tail=None;}(None,Some(next))=>{self.head=Some(Rc::clone(next));next.borrow_mut().prev=None;}(Some(prev),None)=>{self.tail=Some(Rc::clone(prev));prev.borrow_mut().next=None;}(Some(prev),Some(next))=>{next.borrow_mut().prev=Some(Rc::clone(prev));prev.borrow_mut().next=Some(Rc::clone(next));}};}fnpop_back(&mutself)->Option<Rc<RefCell<Node>>>{matchself.tail.take(){Some(tail)=>{self.remove(&tail);Some(tail)}None=>None,}}fnis_empty(&self)->bool{self.head.is_none()}}structLFUCache{cache:HashMap<i32,Rc<RefCell<Node>>>,freq_map:HashMap<i32,LinkedList>,min_freq:i32,capacity:usize,}/** * `&self` means the method takes an immutable reference. * If you need a mutable reference, change it to `&mut self` instead. */implLFUCache{fnnew(capacity:i32)->Self{Self{cache:HashMap::new(),freq_map:HashMap::new(),min_freq:0,capacity:capacityasusize,}}fnget(&mutself,key:i32)->i32{ifself.capacity==0{return-1;}matchself.cache.get(&key){Some(node)=>{letnode=Rc::clone(node);self.incr_freq(&node);letvalue=node.borrow().value;value}None=>-1,}}fnput(&mutself,key:i32,value:i32){ifself.capacity==0{return;}matchself.cache.get(&key){Some(node)=>{letnode=Rc::clone(node);node.borrow_mut().value=value;self.incr_freq(&node);}None=>{ifself.cache.len()==self.capacity{letlist=self.freq_map.get_mut(&self.min_freq).unwrap();self.cache.remove(&list.pop_back().unwrap().borrow().key);}letnode=Rc::new(RefCell::new(Node::new(key,value)));self.add_node(&node);self.cache.insert(key,node);self.min_freq=1;}};}fnincr_freq(&mutself,node:&Rc<RefCell<Node>>){letfreq=node.borrow().freq;letlist=self.freq_map.get_mut(&freq).unwrap();list.remove(node);iflist.is_empty(){self.freq_map.remove(&freq);iffreq==self.min_freq{self.min_freq+=1;}}node.borrow_mut().freq+=1;self.add_node(node);}fnadd_node(&mutself,node:&Rc<RefCell<Node>>){letfreq=node.borrow().freq;matchself.freq_map.get_mut(&freq){Some(list)=>{list.push_front(node);}None=>{letmutlist=LinkedList::new();list.push_front(node);self.freq_map.insert(node.borrow().freq,list);}};}}