LRU Cache

medium

Design a Least Recently Used (LRU) cache with a fixed capacity:

  • LRUCache(capacity) — create the cache with the given positive capacity.
  • get(key) — return the value for key if present, else -1. A get counts as a use.
  • put(key, value) — insert or update key. If the cache exceeds its capacity, evict the least recently used key.

Both get and put must run in O(1) average time. (The first operation names the class and its capacity argument.)

Hints

You need O(1) lookup and O(1) 'which key is least recently used' — one structure can't do both.
Combine a hash map (key -> node) with a doubly linked list ordered by recency.
Every access moves a node to the front; eviction removes the node at the back.

Common doubts

You must unlink an arbitrary node (the one the map points to) in O(1). Without a prev pointer you'd need to find its predecessor, which is O(n).
Just before the tail sentinel — every access moves nodes toward the head, so the oldest drifts to the tail.
They remove all the null-checks for the ends, so inserting at the front and removing at the back are uniform O(1) pointer updates.

Interview follow-ups

Yes — Java's LinkedHashMap, Python's OrderedDict, or JS's Map preserve insertion order and support move-to-end, giving a shorter O(1) LRU. The hash-map-plus-DLL version is what interviews expect you to build.
LFU evicts by lowest access frequency (breaking ties by recency), which needs frequency buckets on top of this structure.

Fun facts

  • LRU is the caching policy behind CPU caches, database buffer pools, and CDN edge caches.
  • The hash-map-plus-doubly-linked-list combo is the canonical 'two structures, two guarantees' design answer.

Asked at

AmazonGoogleMetaMicrosoftBloomberg
Frequently Sometimes Occasionally
Example 1
Input: capacity=2; put(1,1),put(2,2),get(1),put(3,3),get(2)
Output: 1, -1
get(1) returns 1; put(3,3) evicts key 2, so get(2) returns -1.
Example 2
Input: capacity=1; put(2,1),get(2),put(3,2),get(2)
Output: 1, -1
put(3,2) evicts key 2 (capacity 1), so the later get(2) returns -1.
Constraints

- 1 <= capacity <= 3000 - 0 <= key <= 10^4 - 0 <= value <= 10^5 - At most 2 * 10^5 calls to get and put

Solve this problem →