3.0 KiB
3.0 KiB
Challenge: LRU Cache Implementation
Difficulty: Medium Language: Java Subject: Data Structures
Description
In high-performance software engineering, caching is a critical technique used to reduce data retrieval time by storing frequently accessed information in fast-access memory. One of the most common eviction policies is LRU (Least Recently Used). This policy discards the least recently accessed items first when the cache reaches its capacity.
Your task is to design and implement a data structure for an LRU Cache. The cache must support two primary operations: get and put.
get(key): Retrieve the value associated with the key. If the key exists, it should be marked as "recently used." If it doesn't exist, return -1.put(key, value): Insert or update the value for a given key. If the key already exists, update its value and mark it as "recently used." If the key is new and the cache is at full capacity, you must remove the least recently used item before inserting the new one.
The primary constraint is that both get and put operations must run in O(1) average time complexity.
Requirements
- Implement a class
LRUCachethat takes an integercapacityas a constructor argument. - Implement the
get(int key)method:- Return the value if the key exists; otherwise, return -1.
- Moving a key to the "most recently used" position must happen automatically upon access.
- Implement the
put(int key, int value)method:- If the key exists, update the value and move it to the "most recently used" position.
- If the key is new, add it to the cache.
- If the cache exceeds
capacity, remove the entry that was accessed least recently.
- Performance Constraint: You must achieve
O(1)time complexity for both operations. (Hint: Using only a HashMap or only a Linked List will not satisfy the time complexity requirements for both operations simultaneously).
Hints
- To achieve
O(1)lookup, aHashMapis essential. However, a standardHashMapdoes not maintain the order of access. - To achieve
O(1)removal and insertion at specific positions, a Doubly Linked List is the ideal companion to the HashMap. - The HashMap should store the key as the map key and the corresponding Node object (from your Doubly Linked List) as the map value. This allows you to jump directly to the node in the list to re-link it in constant time.
Validation
- Check: Initialize
LRUCache cache = new LRUCache(2). - Sequence:
cache.put(1, 1)cache.put(2, 2)cache.get(1)(Should return 1, and 1 becomes most recent)cache.put(3, 3)(Capacity is 2, so the least recently used key '2' should be evicted)cache.get(2)(Should return -1)cache.get(3)(Should return 3)cache.put(4, 4)(Capacity is 2, so the least recently used key '1' should be evicted)cache.get(1)(Should return -1)cache.get(3)(Should return 3)cache.get(4)(Should return 4)
- Expected Output:
[1, -1, 3, -1, 3, 4]