-
初刷时间:2023.9.25
-
解题思路:
-
所需的数据结构:
- 一个二维数组cache,其中每一项是一个四元组包括{key、value、time、cnt}
- 一个无序map,记录key 和 cache下标的映射关系
- 一个set,其中存的每一项都是三元组{cnt、time、idx},按照从小到大的顺序进行排序
-
核心思路是,用一个se按照cnt和time从小到大的顺序t维护当前cache中各元素,需要进行替换时直接替换set首迭代器位置的元素
-
实现get方法:
- 如果无序map中存在key到idx的映射关系,则返回idx处对应的value
- 除此之外还要更新set,将旧的三元组删去,并存入新的三元组
- 如果不存在映射关系,直接返回-1
-
实现put方法:
- 如果无序map中存在key到idx的映射关系,修改idx处对应的value,更新set
- 如果不存在,但cache未满,直接向cache中的空位置插入新元素,同时插入set
- 如果cache已满,将其替换到set中首迭代器所指向的位置,同时更新set
-
-
解题代码:
class LFUCache {
public:
LFUCache(int capacity) {
len = capacity;
}
int get(int key) {
time += 1;
if(um.count(key))
{
int idx = um[key];
s.erase({cache[idx][3], cache[idx][2], idx});
cache[idx][2] = time;
cache[idx][3] += 1;
s.insert({cache[idx][3], cache[idx][2], idx});
return cache[idx][1];
}
return -1;
}
void put(int key, int value) {
time += 1;
if(um.count(key))
{
int idx = um[key];
s.erase({cache[idx][3], cache[idx][2], idx});
cache[idx][1] = value;
cache[idx][2] = time;
cache[idx][3] += 1;
s.insert({cache[idx][3], cache[idx][2], idx});
return;
}
if(cache.size() < len)
{
int idx = cache.size();
cache.push_back({key, value, time, 1});
um[key] = idx;
s.insert({cache[idx][3], cache[idx][2], idx});
return;
}
//需要替换的情况
auto it = s.begin();//直接替换开头这项
int idx = (*it)[2];
um.erase(cache[idx][0]);
um[key] = idx;
cache[idx][0] = key;
cache[idx][1] = value;
cache[idx][2] = time;
cache[idx][3] = 1;
s.erase(it);
s.insert({cache[idx][3], cache[idx][2], idx});
}
vector<vector<int>> cache;//Key、value、time、cnt
unordered_map<int, int> um;//key、idx
set<vector<int>> s;
int len;
int time = 0;
};
/**
* 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);
*/