146. Lru Cache¶
Difficulty: Medium
LeetCode Problem View on GitHub
146. LRU Cache
Medium
Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.
Implement the LRUCache class:
LRUCache(int capacity)Initialize the LRU cache with positive sizecapacity.int get(int key)Return the value of thekeyif the key exists, otherwise return-1.void put(int key, int value)Update the value of thekeyif thekeyexists. Otherwise, add thekey-valuepair to the cache. If the number of keys exceeds thecapacityfrom this operation, evict the least recently used key.
The functions get and put must each run in O(1) average time complexity.
Example 1:
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
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 {4=4, 3=3}
lRUCache.get(1); // return -1 (not found)
lRUCache.get(3); // return 3
lRUCache.get(4); // return 4
Constraints:
1 <= capacity <= 30000 <= key <= 1040 <= value <= 105- At most
2 * 105calls will be made togetandput.
Solution¶
class LRUCache {
static class Node {
Node prev, next;
int val;
public Node(int val) {
this.val = val;
prev = null;
next = null;
}
}
private Node head;
private Node tail;
private int totalNodes;
private int n;
private HashMap<Integer, Integer> map;
private HashMap<Integer, Node> nodeMap;
public LRUCache(int capacity) {
this.head = null;
this.tail = null;
this.totalNodes = 0;
this.n = capacity;
map = new HashMap<>();
nodeMap = new HashMap<>();
}
public int get(int key) {
if (map.containsKey(key)) {
int res = map.get(key);
deletePrevRef(key);
addFront(key);
return res;
}
return -1;
}
public void put(int key, int value) {
if (map.containsKey(key)) {
deletePrevRef(key);
addFront(key);
map.remove(key);
map.put(key, value);
}
else if (totalNodes == n) {
/* I need to delete something */
int deletedKey = deleteLast();
map.remove(deletedKey);
map.put(key, value);
addFront(key);
}
else {
/* I want to make a node of this value */
if (map.containsKey(key)) {
map.remove(key);
deletePrevRef(key);
map.put(key, value);
addFront(key);
}
else {
map.put(key, value);
addFront(key);
}
}
}
private int deleteLast() {
totalNodes--;
int ans = tail.val;
nodeMap.remove(ans);
if (totalNodes == 0) {
head = null;
tail = null;
}
else {
tail = tail.prev;
tail.next = null;
}
return ans;
}
private void deletePrevRef(int key) {
totalNodes--;
if (totalNodes == 0) {
head = null;
tail = null;
return;
}
Node refNode = nodeMap.get(key);
if (refNode.prev == null) {
/* want to delete the head node */
head = refNode.next;
head.prev = null;
return;
}
if (refNode.next == null) {
/* want to delete the tail node*/
tail = tail.prev;
tail.next = null;
}
else {
refNode.prev.next = refNode.next;
refNode.next.prev = refNode.prev;
}
}
private void deletePrev(int key) {
totalNodes--;
if (totalNodes == 0) {
head = null;
tail = null;
return;
}
Node temp = head;
if (temp.val == key) {
head = temp.next;
head.prev = null;
return;
}
while (temp != null) {
if (temp.val == key) {
if (temp.next == null) {
tail = tail.prev;
tail.next = null;
}
else {
temp.prev.next = temp.next;
temp.next.prev = temp.prev;
}
}
temp = temp.next;
}
}
private void addFront(int val) {
if (head == null) {
head = new Node(val);
tail = head;
nodeMap.put(val, head);
}
else {
Node newNode = new Node(val);
head.prev = newNode;
newNode.next = head;
head = newNode;
head.prev = null;
nodeMap.put(val, head);
}
totalNodes++;
}
private void print() {
Node temp = head;
while (temp != null) {
System.out.print(temp.val + " ");
temp = temp.next;
}
System.out.println();
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/
Complexity Analysis¶
- Time Complexity:
O(?) - Space Complexity:
O(?)
Approach¶
Detailed explanation of the approach will be added here