LFU缓存中元素的换入换出由两个排序码决定:使用次数cont和时间戳time。定义struct结点并且重写<运算符函数,使用红黑树保存结点,就能实现结点按要求自动排序,另外再使用哈希表保存<key,node>,实现了通过key的查找。然后在get和set的过程中更新cont及time,并且元素装满时进行换出。
struct Node{
int key;
int value;
int cont;
int time;
Node(int k,int v,int c,int t):key{k},value{v},cont{c},time{t}{};
bool operator<(const Node& node) const{
return cont==node.cont?time<node.time:cont<node.cont;
}
};
class Solution {
public:
/**
* lfu design
* @param operators int整型vector<vector<>> ops
* @param k int整型 the k
* @return int整型vector
*/
int get(int key){
if(capacity==0) return -1;
auto iter=hash_map.find(key);
if(iter!=hash_map.end()){
Node node=iter->second;
hash_map.erase(iter);
lfu_set.erase(node);
node.cont++;
node.time=++time;
hash_map.insert(make_pair(key,node));
lfu_set.insert(node);
return node.value;
}
else return -1;
}
void set(int key,int value){
auto iter=hash_map.find(key);
if(iter!=hash_map.end()){
Node node=iter->second;
hash_map.erase(iter);
lfu_set.erase(node);
node.cont++;
node.time=++time;
node.value=value;
hash_map.insert(make_pair(key,node));
lfu_set.insert(node);
}
else{
if(hash_map.size()>=capacity){
hash_map.erase(lfu_set.begin()->key);
lfu_set.erase(lfu_set.begin());
}
Node node{key,value,1,++time};
hash_map.insert(make_pair(key, node));
lfu_set.insert(node);
}
}
vector<int> LFU(vector<vector<int> >& operators, int k) {
vector<int> result{};
capacity=k;
time=0;
for(auto x:operators){
if(x[0]==1) set(x[1], x[2]);
else if(x[0]==2) result.push_back(get(x[1]));
}
return result;
}
private:
int capacity;
int time;
std::set<Node> lfu_set;
unordered_map<int, Node> hash_map;
};