link
class LFUCache {
public:
unordered_map<int,int> ktov; // key to value
unordered_map<int,int> ktof; //key to freq
unordered_map<int,list<int>> ftol; // freq to list
unordered_map<int,list<int>::iterator> ktoi; //key to iter
int cap;
int minfreq;
int size;
LFUCache(int capacity) {
cap=capacity;
minfreq=0;
size=0;
}
int get(int key) {
if(ktov.find(key)==ktov.end()) return -1;
int prefreq=ktof[key];
ftol[prefreq].erase(ktoi[key]);
int newfreq=prefreq+1;
ktof[key]=newfreq;
ftol[newfreq].push_back(key);
ktoi[key]=--ftol[newfreq].end();
if(ftol[minfreq].empty()){
++minfreq;
}
return ktov[key];
}
void put(int key, int value) {
if(cap<=0) return;
if(ktov.find(key)!=ktov.end()){
ktov[key]=value;
int prefreq=ktof[key];
ftol[prefreq].erase(ktoi[key]);
int newfreq=prefreq+1;
ktof[key]=newfreq;
ftol[newfreq].push_back(key);
ktoi[key]=--ftol[newfreq].end();
if(ftol[minfreq].empty()){
++minfreq;
}
}else{
if(size>=cap){
--size;
int del=ftol[minfreq].front();
ftol[minfreq].pop_front();
ktov.erase(del);
ktof.erase(del);
ktoi.erase(del);
}
ktov[key]=value;
ktof[key]=1;
minfreq=1;
ftol[1].push_back(key);
ktoi[key]=--ftol[1].end();
++size;
}
}
};
/**
* 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);
*/