-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLeetCode146.java
More file actions
93 lines (76 loc) · 2.12 KB
/
LeetCode146.java
File metadata and controls
93 lines (76 loc) · 2.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
The reason why we use Map + double linked list is that:
1. Map provides O(1) access time to get item by key
IMPORTANT!!!
2. Double linked list provides O(1) time to remove and add node because
it doesn't require to traverse the list to find the previous node and next node.
Thus, the tips are to use Map to get the node, then due to double linked list, we can remove and add the node in O(1) time.
*/
class LRUCache {
public static class Node{
int key, val;
Node pre, next;
public Node(int key, int val){
this.key = key;
this.val = val;
}
}
private int capacity;
private Map<Integer, Node> map;
private Node head;
private Node dummy;
public LRUCache(int capacity) {
this.capacity = capacity;
this.map = new HashMap<>();
this.head = new Node(0, 0);
this.dummy = new Node(0, 0);
head.next = dummy;
dummy.pre = head;
}
public int get(int key) {
Node n = map.get(key);
if (n == null) return -1;
moveToHead(n);
return n.val;
}
public void put(int key, int val) {
if (map.containsKey(key)){
Node n = map.get(key);
n.val = val;
moveToHead(n);
return;
}
Node newNode = new Node(key, val);
map.put(key, newNode);
addAfterHead(newNode);
if (map.size() > capacity){
Node lru = popTail();
map.remove(lru.key);
}
}
private void remove(Node n){
n.pre.next = n.next;
n.next.pre = n.pre;
}
private void addAfterHead(Node n){
n.next = head.next;
n.pre = head;
head.next.pre = n;
head.next = n;
}
private void moveToHead(Node n) {
remove(n);
addAfterHead(n);
}
private Node popTail() { // remove LRU
Node lru = dummy.pre;
remove(lru);
return lru;
}
}
/**
* 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);
*/