0%

LFU Cache

460. LFU Cache

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class LFUCache {
struct LFUItem {
int key;
int value;
int freq;
LFUItem() {}
LFUItem(int key, int value, int freq) : key(key), value(value), freq(freq) {}
};

int capacity;
int min_freq;
unordered_map<int, list<LFUItem>> freq_to_list;
unordered_map<int, list<LFUItem>::iterator> key_to_iter;

public:
LFUCache(int capacity) {
this->capacity = capacity;
this->min_freq = 1;
}

int get(int key) {
if (capacity <= 0) return -1;

auto it = key_to_iter.find(key);
if (it == key_to_iter.end()) return -1;
int value = it->second->value;
put(key, value);
return value;
}

void put(int key, int value) {
if (capacity <= 0) return;

auto it = key_to_iter.find(key);
if (it != key_to_iter.end()) {
auto list_node = it->second;
freq_to_list[list_node->freq + 1].push_back(LFUItem(key, value, list_node->freq + 1));
key_to_iter[key] = prev(freq_to_list[list_node->freq + 1].end());
freq_to_list[list_node->freq].erase(list_node);
if (freq_to_list[min_freq].empty()) min_freq++;
} else {
if (key_to_iter.size() == capacity) {
key_to_iter.erase(freq_to_list[min_freq].begin()->key);
freq_to_list[min_freq].pop_front();
}
min_freq = 1;
freq_to_list[min_freq].push_back(LFUItem(key, value, min_freq));
key_to_iter[key] = prev(freq_to_list[min_freq].end());
}
}
};