Link: https://leetcode.com/problems/lfu-cache/
Solution:
Topics: linked list, hash map, SortedList, LRUcache
Intuition
This is a great problem and a very nice twist on the LRUcache problem. Basically, we must remove the least frequently used element and in the case of a tie, we remove the least recent.
The key is to store nodes in their own doubly linked lists by frequency…that way when we must remove the least frequent, we just key into the smallest count and then remove the tail of that list (because the tail would be the least recently used).
There is one slight complication for the get
method. We must remove the node from its current list and insert it into the count+1
list. Its also useful to delete empty lists as the number of lists can get very high.
The put
method is slightly tricky…we have a hash map of lists that are keyed by frequency, so how do we get the least frequent key? Well one way would be to take the min of the keys, but this is not the most efficient operation. SortedDict
is very useful here, because its essentially a hash map sorted by key (red-black tree) and we will be able to always access the least frequent (key, value) using the peakitem(0)
method.
The implementation is not too bad if we use the lessons learned from LRUcache. Algorithmically, cache policies are not terribly interesting but the implementation is definitely a useful exercise in OOP (especially this one).
Implementation
Mnemonic
Imagine pieces of string hanging from another piece of string.
Visual
Review 1
Nice problem. I solved it mentally because implementation would take a while. Revisit when preparing for OOP.
Review 2
I re-implemented it. Still a nightmare of edge-cases.