Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.
Implement the LRUCache
class:
LRUCache(int capacity)
Initializes the LRU cache with positive size capacity
.int get(int key)
Returns the value of the key
if the key
exists, otherwise returns -1
.void put(int key, int value)
Updates the value of the key
if the key
exists. Otherwise, adds the key-value
pair to the cache. If the number of keys exceeds the capacity
from this operation, evict the least recently used key.The functions get
and put
must each run in O(1) average time complexity.
Example:
Input:
["LRUCache","put","put","get","put","get","put","get","get","get"]
[[2],[1,1],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]]
Output:
[null,null,null,1,null,-1,null,-1,3,4]
Explanation:
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // cache is {1=1}
lRUCache.put(2, 2); // cache is {1=1, 2=2}
lRUCache.get(1); // return 1
// cache is {2=2, 1=1}
lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3}
lRUCache.get(2); // returns -1 (not found)
lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {3=3, 4=4}
lRUCache.get(1); // return -1 (not found)
lRUCache.get(3); // return 3
lRUCache.get(4); // return 4
-1
.To achieve O(1) time complexity for both get
and put
operations, we can use a combination of:
HashMap
to store key-value pairs for O(1) access.HashMap
will map keys to the corresponding node in the doubly linked list.HashMap
.-1
.HashMap
.HashMap
.import java.util.HashMap;
class LRUCache {
private class Node {
int key;
int value;
Node prev;
Node next;
Node(int key, int value) {
this.key = key;
this.value = value;
}
}
private final int capacity;
private final HashMap<Integer, Node> map;
private final Node head;
private final Node tail;
public LRUCache(int capacity) {
this.capacity = capacity;
this.map = new HashMap<>();
this.head = new Node(0, 0);
this.tail = new Node(0, 0);
head.next = tail;
tail.prev = head;
}
public int get(int key) {
if (!map.containsKey(key)) return -1;
Node node = map.get(key);
remove(node);
insertToFront(node);
return node.value;
}
public void put(int key, int value) {
if (map.containsKey(key)) {
Node node = map.get(key);
node.value = value;
remove(node);
insertToFront(node);
} else {
if (map.size() == capacity) {
map.remove(tail.prev.key);
remove(tail.prev);
}
Node newNode = new Node(key, value);
map.put(key, newNode);
insertToFront(newNode);
}
}
private void remove(Node node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void insertToFront(Node node) {
Node temp = head.next;
head.next = node;
node.prev = head;
node.next = temp;
temp.prev = node;
}
}
HashMap
and the doubly linked list.Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?