146. LRU Cache
in Coding Interview on Medium, Design, HashMap, Linked List
LRU(최소 사용) 캐시의 제약 조건을 따르는 데이터 구조를 설계
- int get(int key) Return the value of the key if the key exists, otherwise return -1.
- void put(int key, int value) Update the value of the key if the key exists. Otherwise, add 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.
// Least Recently Used (LRU) cache.
class LRUCache {
private Map<Integer, Node> cache; // map key to node
private int capacity;
private Node left;
private Node right;
// 가장 최근에 사용된 데이터 캐쉬
public LRUCache(int capacity) {
this.capacity = capacity;
cache = new HashMap<>();
//left = LRU , right = most recent
this.left = new Node(0, 0);
this.right = new Node(0, 0);
this.left.next = this.right;
this.right.prev = this.left;
}
public int get(int key) {
if (cache.containsKey(key)) {
// update most recent
remove(cache.get(key));
insert(cache.get(key));
return cache.get(key).val;
} else {
return -1;
}
}
public void put(int key, int value) {
// 존재하면 지우고 뒤에 추가한다.
if (cache.containsKey(key)) {
remove(cache.get(key));
}
// update the value of the key if the key exists.
cache.put(key, new Node(key, value));
insert(cache.get(key));
if (cache.size() > capacity) {
// remove from the list and delete the LRU from the hashmap
Node lru = this.left.next;
remove(lru);
cache.remove(lru.key);
}
}
////////////////////////////////////////////////////////////////////
// remove node from list
private void remove(Node node) {
Node prev = node.prev;
Node next = node.next;
prev.next = next;
next.prev = prev;
}
// insert node at right
private void insert(Node node) {
Node prev = this.right.prev;
Node next = this.right;
prev.next = node;
next.prev = node;
node.next = next;
node.prev = prev;
}
private class Node {
private int key;
private int val;
Node next;
Node prev;
public Node(int key, int val) {
this.key = key;
this.val = val;
}
}
}
/**
* 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);
*/