1. Topic
Design and implement the least frequently used (LFU) cache data structure. It should support the following operations: get and put.
get(key)
- If the key exists in the cache, then get the value (always positive) key, otherwise -1.put(key, value)
- if the key does not exist, or insert set value.- When the cache reaches its capacity, it should be in before inserting a new project, the project is not the most frequently used is invalid.
- In this problem, when there is a tie (i.e., two or more keys having the same frequency), the least recently used key is removed.
Advanced:
you can (1) O performs two operations within the time complexity?
示例:
LFUCache cache = new LFUCache( 2 /* capacity (缓存容量) */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 去除 key 2
cache.get(2); // 返回 -1 (未找到key 2)
cache.get(3); // 返回 3
cache.put(4, 4); // 去除 key 1
cache.get(1); // 返回 -1 (未找到 key 1)
cache.get(3); // 返回 3
cache.get(4); // 返回 4
Source: stay button (LeetCode)
link: https: //leetcode-cn.com/problems/lfu-cache
copyrighted by deduction from all networks. Commercial reprint please contact the authorized official, non-commercial reprint please indicate the source.
2. Problem Solving
- A similar topic: LeetCode the LRU 146. The cache mechanism (hash chain)
class node{
public:
int k, v, f;
node(int key, int val, int freq):k(key),v(val),f(freq){}
};
class LFUCache {
unordered_map<int, list<node>::iterator> kPos;//key 对应的节点迭代器位置
unordered_map<int, list<node>> freq_list;//不同的频数下挂着一条双链表,尾部是最少使用的
int cap;
int minfreq;
int size;
public:
LFUCache(int capacity) {
cap = capacity;
minfreq = 0;
size = 0;
}
int get(int key) {
if(kPos.find(key)==kPos.end())
return -1;
auto it = kPos[key];
int f = it->f;
int v = it->v;
if(f == minfreq && freq_list[f].size() == 1)
minfreq++;
freq_list[f].erase(it);
freq_list[++f].push_front(node(key,v,f));
kPos[key] = freq_list[f].begin();
return v;
}
void put(int key, int value) {
if(kPos.find(key)!=kPos.end())
{
auto it = kPos[key];
int f = it->f;
if(f == minfreq && freq_list[f].size()==1)
minfreq++;
freq_list[f].erase(it);
freq_list[++f].push_front(node(key,value,f));
kPos[key] = freq_list[f].begin();
}
else if(size < cap)
{
minfreq = 1;
freq_list[minfreq].push_front(node(key,value,1));
kPos[key] = freq_list[1].begin();
size++;
}
else if(cap != 0 && size == cap)
{
auto Node = freq_list[minfreq].back();
int k = Node.k;
freq_list[minfreq].pop_back();
kPos.erase(k);
size--;
put(key, value);
}
}
};
228 ms 40 MB