LRU Cache
Problem
Design a Least-Recently-Used (LRU) cache with O(1) get and put.
Implement LRUCache(int capacity), int get(int key) — return the value or -1 if absent; void put(int key, int value) — insert or update. When the cache is at capacity, evict the least recently used key before inserting. Both get and put count as "using" a key.
Constraints
- 1 ≤ capacity ≤ 3000
- 0 ≤ key, value ≤ 10⁴
- at most 2·10⁵ calls
- get and put must each be O(1)
Approach — Linked List
This is a Linked List problem. The idea: rework the list with careful pointer manipulation — often a dummy head and fast/slow pointers — in a single pass. Work through the reference code below line by line, then re-derive it yourself in the editor — that's how the pattern sticks.
Complexity: O(n) time, O(1) space.
Solution code
Python
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity):
self.cap = capacity
self.cache = OrderedDict()
def get(self, key):
if key not in self.cache:
return -1
self.cache.move_to_end(key)
return self.cache[key]
def put(self, key, value):
if key in self.cache:
self.cache.move_to_end(key)
self.cache[key] = value
if len(self.cache) > self.cap:
self.cache.popitem(last=False)
Java
import java.util.HashMap;
import java.util.Map;
class LRUCache {
// Doubly linked list node — most-recent near head, LRU near tail.
private static class Node {
int key, value;
Node prev, next;
Node(int k, int v) { key = k; value = v; }
}
private final int capacity;
private final Map<Integer, Node> map;
private final Node head, tail; // sentinels
public LRUCache(int capacity) {
this.capacity = capacity;
this.map = new HashMap<>();
head = new Node(0, 0);
tail = new Node(0, 0);
head.next = tail;
tail.prev = head;
}
public int get(int key) {
Node node = map.get(key);
if (node == null) return -1;
moveToFront(node);
return node.value;
}
public void put(int key, int value) {
Node node = map.get(key);
if (node != null) {
node.value = value;
moveToFront(node);
return;
}
if (map.size() == capacity) {
Node lru = tail.prev; // least recently used
unlink(lru);
map.remove(lru.key);
}
Node fresh = new Node(key, value);
map.put(key, fresh);
addToFront(fresh);
}
private void unlink(Node n) {
n.prev.next = n.next;
n.next.prev = n.prev;
}
private void addToFront(Node n) {
n.next = head.next;
n.prev = head;
head.next.prev = n;
head.next = n;
}
private void moveToFront(Node n) {
unlink(n);
addToFront(n);
}
}
Practice it
Reading a solution isn't the same as being able to write it under pressure. Open this problem in the in-browser editor, hide the solution, and solve it from scratch — your code runs against real test cases instantly.
Solve LRU Cache interactively → ← All solutions