-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathLRUCache.java
140 lines (120 loc) · 2.52 KB
/
LRUCache.java
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* Daily coding problem #52
* Implement an least recently used cache of size n
* with the following methods:
* set(key, value) - if there are already n items in the cache,
* remove the recently used item and add the new item
* get(key) - get value at key, if doesn't exist return null
*/
// using doubly linkedlist (like a queue) - O(1) for insert and delete)
// and a hashmap (O(1) look up node in the linkedlist)
// add new item at the head of linkedlist, remove LRU item from tail
// update hashmap accordingly
// both get() and set() operations will move node to the head position
// if it's not already at the head position
public class Node
{
int key;
int value;
Node next = null;
Node prev = null;
public Node(int key, int value)
{
this.key = key;
this.value = value;
}
public class LRUCache
{
int size;
HashMap<Integer, Node> map = new HashMap<>();
Node head = null;
Node tail = null;
public LRUCache(int size)
{
this.size = size;
}
// return Integer because qs says to return null if item doesn't exist
public Integer get(int key)
{
Integer retValue;
if(map.contains(key))
{
Node node = map.get(key);
retValue = node.value();
//move the node from its current position to the head (most recently used)
if(node != head)
{
remove(node);
setHead(node);
}
}
else
{
retValue = null;
}
return retValue;
}
private void remove(Node node)
{
// node is the tail
if(node.next == null)
{
tail = node.prev;
tail.next = null;
node.prev = null;
}
// node is not tail
else
{
node.prev.next = node.next;
node.next.prev = node.prev;
node.next = null;
node.prev = null;
}
}
private void setHead(Node node)
{
// empty linkedlist
if(map.isEmpty())
{
head = node;
tail = node;
}
else
{
node.next = head;
head.prev = node;
head = node;
}
}
public void set(int key, int value)
{
// key is in the linkedlist/map
if(map.contains(key))
{
Node node = map.get(key);
// in case value to set is new
node.value = value;
if(node != head)
{
remove(node);
setHead(node);
}
}
// key is not in the linkedlist/map but hasn't reached capacity - add Node
else if(map.size() < size)
{
Node node = new Node(key, value);
setHead(node);
map.put(key, node);
}
// key is not in the linkedlist but capacity is full - remove LRU node then add Node
else
{
map.remove(tail.key);
remove(tail);
Node node = new Node(key, value);
setHead(node);
map.put(key, node);
}
}
}