LFU Cache - Complete Solution Guide
LFU Cache is LeetCode problem 460, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
Design and implement a data structure for a Least Frequently Used (LFU) cache. Implement the LFUCache class: LFUCache(int capacity) Initializes the object with the capacity of the data structure. int get(int key) Gets the value of the key if the key exists in the cache. Otherwise, returns -1 . void put(int key, int value) Update the value of the key if present, or inserts the key if not already present. When the cache reaches its capacity , it should invalidate and remove the least frequently us
Detailed Explanation
The problem asks us to design and implement a Least Frequently Used (LFU) cache with a given capacity. The cache should support two operations: `get(key)` and `put(key, value)`. `get(key)` retrieves the value associated with the key if it exists; otherwise, it returns -1. `put(key, value)` either updates the value if the key exists or inserts a new key-value pair. When the cache is full, the least frequently used key should be evicted. If there is a tie in frequency, the least recently used key should be evicted. A use counter is maintained for each key. When the cache is initialized, the use counter is 1. When a key is accessed via `get` or `put`, its counter increments.
Solution Approach
The solution uses three main data structures: `key_to_val` (a HashMap to store key-value pairs), `key_to_freq` (a HashMap to store the frequency of each key), and `freq_to_keys` (a HashMap where keys are frequencies, and values are OrderedDicts or LinkedHashSets representing the keys with that frequency). The `min_freq` variable tracks the minimum frequency in the cache. The `get` operation retrieves the value, increments the key's frequency, and moves the key to the corresponding frequency list. The `put` operation updates the value if the key exists, otherwise, if the cache is full, the least frequently and least recently used key is evicted, and the new key-value pair is inserted with frequency 1.
Step-by-Step Algorithm
- Step 1: **Initialization:** Create the necessary HashMaps and the `min_freq` variable.
- Step 2: **`get(key)`:** a. Check if the key exists in `key_to_val`. If not, return -1. b. Get the current frequency of the key from `key_to_freq`. c. Remove the key from the OrderedDict associated with the current frequency in `freq_to_keys`. d. If the OrderedDict for the current frequency is now empty and the current frequency is equal to `min_freq`, increment `min_freq`. e. Increment the frequency of the key in `key_to_freq`. f. Add the key to the OrderedDict associated with the new frequency in `freq_to_keys`. g. Return the value from `key_to_val`.
- Step 3: **`put(key, value)`:** a. If the cache capacity is 0, return. b. If the key exists in `key_to_val`, update the value and call `get(key)` to update frequency and move it to correct frequency bucket. c. If the cache is full, remove the least frequently and least recently used key: i. Get the least frequently used key from the head of the OrderedDict associated with `min_freq` in `freq_to_keys`. ii. Remove the key from `key_to_val` and `key_to_freq`. d. Insert the new key-value pair: i. Add the key-value pair to `key_to_val`. ii. Set the frequency of the key to 1 in `key_to_freq`. iii. Add the key to the OrderedDict associated with frequency 1 in `freq_to_keys`. iv. Set `min_freq` to 1.
Key Insights
- Insight 1: We need to keep track of the frequency of each key and the order in which keys with the same frequency were accessed.
- Insight 2: Using a combination of HashMaps and Doubly Linked Lists (or OrderedDict in Python) allows for O(1) average time complexity for both `get` and `put` operations.
- Insight 3: Maintaining a `min_freq` variable is crucial for efficiently identifying the least frequently used keys for eviction.
Complexity Analysis
Time Complexity: O(1)
Space Complexity: O(capacity)
Topics
This problem involves: Hash Table, Linked List, Design, Doubly-Linked List.
Companies
Asked at: Citadel, Coupang, DoorDash, Gameskraft, KLA, PayPal, Rippling, Salesforce, ServiceNow, Siemens, Visa, Walmart Labs, Zomato.