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());         }     } };
  |