146. LRU Cache
Time complexity : O(1) both for put and get since all operations with ordered dictionary :
get/in/set/move_to_end/popitem (get/containsKey/put/remove) are done in a constant time.
Space complexity : O(capacity) since the space is used only for
an ordered dictionary with at most capacity + 1 elements.
notice: init head, map operation do first
class LRUCache {
class DoubleLinkedListNode {
int key;
int val;
DoubleLinkedListNode prev, next;
DoubleLinkedListNode(int key, int val) {
this.key = key;
this.val = val;
this.prev = null;
this.next = null;
}
}
private Map<Integer, DoubleLinkedListNode> map;
private DoubleLinkedListNode head;
private DoubleLinkedListNode tail;
private int capacity;
public LRUCache(int capacity) {
this.head = new DoubleLinkedListNode(-1, -1); // dummy node, remember init
this.tail = head;
this.map = new HashMap<>();
this.capacity = capacity;
}
public int get(int key) {
if (!map.containsKey(key)) {
return -1;
}
DoubleLinkedListNode curr = map.get(key);
remove(curr);
moveToFront(curr);
return curr.val;
}
public void put(int key, int value) {
// just reuse get()
if (get(key) != -1) {
map.get(key).val = value;
return;
}
if (map.size() == capacity) { //超出缓存上限
//map.remove(head.next.key); //刪除 tail data
// head.next = head.next.next;
// head.next.prev = head;
map.remove(tail.key); // map operation do first
remove(tail);
}
DoubleLinkedListNode insert = new DoubleLinkedListNode(key, value); //新建节点
map.put(key, insert);
moveToFront(insert);
}
// 2 cases
// node1 <-> node2
// node1 -> node -> null
public void remove(DoubleLinkedListNode node) {
DoubleLinkedListNode prev = node.prev;
prev.next = node.next;
if (node.next != null) {
node.next.prev = prev;
} else {
tail = prev;
}
}
// 2 cases
// head -> new node -> node1
// head -> new node -> null
private void moveToFront(ListNode node) {
if (head.next == null) {
head.next = node;
node.prev = head;
tail = node;
} else {
node.next = head.next;
node.next.prev = node;
head.next = node;
node.prev = head;
}
}
}
/**
* 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);
if > capacity, evict last,
if (key in middle or last, ) delete by linkedlist O(1), find use hashmapO(1)
if (key exist update it, move to last
add new to last
*/
Last updated