缓存置换_LRU与LFU算法的C++实现
一、LRU算法的实现
示例1
输入
[[1,1,1],[1,2,2],[1,3,2],[2,1],[1,4,4],[2,2]],3
返回值
[1,-1]
class LRUCache {
class Node{
public:
Node(){}
Node(int k, int v): \
k_(k), v_(v){}
int k_, v_;
};
void addNode(int k, int v){
auto it = keyMap.find(k);
Node node(k, v);
if(it != keyMap.end()){
removeNode(it->second);
}
ls.push_back(move(node));
keyMap.insert({k, --ls.end()});
}
void removeNode(list<Node>::iterator it){
keyMap.erase(it->k_);
ls.erase(it);
}
list<Node> ls;
unordered_map<int, list<Node>::iterator> keyMap;
int capacity_ = 0;
public:
LRUCache(int capacity): capacity_(capacity) {
}
int get(int key) {
if(capacity_ == 0) return -1;
int ans = -1;
auto it = keyMap.find(key);
if(it == keyMap.end()){
return ans;
} else {
ans = keyMap[key]->v_;
removeNode(it->second);
addNode(key, ans);
}
return ans;
}
void put(int key, int value) {
auto it = keyMap.find(key);
if(it == keyMap.end()){
if(capacity_ == keyMap.size()){
removeNode(ls.begin());
}
} else {
removeNode(it->second);
}
addNode(key, value);
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/
二、LFU算法的实现
示例1
输入
[[1,1,1],[1,2,2],[1,3,2],[1,2,4],[1,3,5],[2,2],[1,4,4],[2,1]],3
返回值
[4,-1]
说明
在执行"1 2 4"后,"1 1 1"被删除。因此第二次询问的答案为-1
class LFUCache {
class Node{
public:
Node(){}
Node(int k, int v, int freq): \
k_(k), v_(v), freq_(freq){}
int k_, v_, freq_ = 1;
};
void addNode(int k, int v, int freq){
freqMap[freq].push_back(Node(k, v, freq));
keyMap[k] = --freqMap[freq].end();
}
void removeNode(int freq, list<Node>::iterator it){
keyMap.erase(it->k_);
freqMap[freq].erase(it);
if(freqMap[freq].size() == 0){
freqMap.erase(freq);
if(minFreq_ == freq) ++minFreq_;
}
}
unordered_map<int, list<Node>::iterator> keyMap;
unordered_map<int, list<Node>> freqMap;
int capacity_ = 0;
int minFreq_ = 0;
public:
LFUCache(int capacity): capacity_(capacity) {}
int get(int key) {
if(capacity_ == 0) return -1;
auto iter = keyMap.find(key);
if(iter == keyMap.end()) return -1;
list<Node>::iterator it = iter->second;
int ans = it->v_, freq = it->freq_;
removeNode(freq, it);
addNode(key, ans, freq + 1);
return ans;
}
void put(int key, int value) {
if(capacity_ == 0) return;
auto iter = keyMap.find(key);
//key not existed
if(iter == keyMap.end()){
if(keyMap.size() == capacity_){
auto it = freqMap[minFreq_].begin();
removeNode(minFreq_, it);
}
addNode(key, value, 1);
minFreq_ = 1;
} else {
//existed, replace
list<Node>::iterator it = iter->second;
int v = it->v_, freq = it->freq_;
removeNode(freq, it);
addNode(key, value, freq + 1);
}
}
};
/**
* 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);
*/