The problem with naïve

Sorting by frequency = O(log N) each op. Too slow for large caches.

Advertisement

O(1) design

class LFU {
  Map keyMap;      // key → node
  Map> freqMap;  // freq → ordered list of nodes
  int minFreq;
  int capacity;
}
class Node { int key, val, freq; }
Advertisement

Get operation

public int get(int key) {
  Node n = keyMap.get(key);
  if (n == null) return -1;
  // Remove from current freq list, add to next
  freqMap.get(n.freq).remove(n);
  if (freqMap.get(minFreq).isEmpty() && n.freq == minFreq) minFreq++;
  n.freq++;
  freqMap.computeIfAbsent(n.freq, k -> new LinkedList<>()).addFirst(n);
  return n.val;
}

Eviction

Remove least recent from freqMap[minFreq]. Combines LFU with LRU tiebreaking.