AlgoInsight

DSA problem

LRU Cache

MediumData Structure DesignPattern: Data Structure Designtop75FreeAmazonGoogleMicrosoftMetaBloombergApple

Design a data structure that follows the Least Recently Used (LRU) cache eviction policy. Implement an LRUCache class with these operations: LRUCache(capacity) constructs a cache that holds at most capacity key-value pairs; get(key) returns the value if the key exists or -1 otherwise, and marks the key as most recently used; put(key, value) inserts or updates the key, marking it most recently used, and evicts the least recently used key if the cache exceeds capacity. Both operations must run in O(1) average time.

A hash map alone gives O(1) lookup but no ordering. A linked list alone gives O(1) insert/remove if you have the node pointer but O(n) lookup. The classic LRU design combines them: a hash map from key to a node in a doubly linked list, and a doubly linked list ordered by recency — most recently used at the head, least recently used at the tail. The hash map gives instant access to any node; the list gives instant reordering.

Use dummy head and tail sentinels to eliminate every null check during splice operations. Each node holds the key, the value, and prev/next pointers. The key is stored on the node (not just in the map) because eviction needs to remove the map entry for the LRU node, and you cannot get the key back from the node without storing it there.

The core helper operations are removeNode(node) (unlink from current position) and addToFront(node) (insert right after the head sentinel). get does removeNode + addToFront on a hit. put either updates and moves to front, or creates a new node, links it at the front, and — if size exceeds capacity — unlinks the tail.prev node and deletes its key from the map. Every operation touches at most a constant number of pointers, so both are truly O(1).

Examples

Example 1
Input: LRUCache(2); put(1,1); put(2,2); get(1); put(3,3); get(2)
Output: [1, -1]
Explanation: After put(3,3) the cache is full and key 2 (least recently used) is evicted, so get(2) returns -1.
Example 2
Input: LRUCache(2); put(1,1); put(2,2); put(1,10); get(1)
Output: 10
Explanation: put on an existing key updates the value and marks the key as most recently used.
Example 3
Input: LRUCache(1); put(1,1); put(2,2); get(1)
Output: -1
Explanation: Capacity 1 means key 1 is evicted as soon as key 2 is inserted, so get(1) returns -1.

Constraints

3 hints and a full solution walkthrough with step-by-step visualizations are available in the practice editor.

designhash-tablelinked-listdoubly-linked-list

Browse all DSA problems