
Solution:维护一个HashMap和一个DoubleLinkedList
- 实现get()可以用HashMap,复杂度O(1)
- 可以用一个队列LinkedList来实现“顺序”。
- 在put()添加元素时,有addToFirst和remove这两个操作。LinkedList添加到头部复杂度为O(1)。remove为O(N),因为节点不知道前一个节点。
- 因此,使用DoubleLinkedList,可以满足remove的O(1),因为每个节点都知道pre和next。
class LRUCache {
class Node {
int key, value;
Node pre, next;
public Node(int key, int value) {
this.key = key;
this.value = value;
}
public Node() {}
}
int capacity;
int count = 0;
Node head, tail;
Map<Integer, Node> map;
public LRUCache(int capacity) {
this.capacity = capacity;
this.head = new Node();
this.tail = new Node();
head.next = tail;
tail.pre = head;
map = new HashMap<>();
}
public int get(int key) {
if (map.containsKey(key)) {
updateNode(map.get(key));
return map.get(key).value;
} else {
return -1;
}
}
public void put(int key, int value) {
if (map.containsKey(key)) {
map.get(key).value = value;
updateNode(map.get(key));
} else {
Node node = new Node(key, value);
map.put(key, node);
addNodeToFirst(node);
if (count > capacity) {
map.remove(tail.pre.key);
removeNode(tail.pre);
}
}
}
public void updateNode(Node node) {
removeNode(node);
addNodeToFirst(node);
}
public void addNodeToFirst(Node node) {
node.pre= head;
node.next = head.next;
head.next.pre = node;
head.next = node;
count++;
}
public void removeNode(Node node) {
node.pre.next = node.next;
node.next.pre = node.pre;
count--;
}
public void resize(int newCapacity) {
this.capacity = newCapacity;
while (count > capacity) {
Node toRemove = tail.pre;
map.remove(toRemove.key);
removeNode(toRemove);
}
}
}
How to make it thread safe?
public synchronized int get(int key) {
if (map.containsKey(key)) {
updateNode(map.get(key));
return map.get(key).value;
} else {
return -1;
}
}
public synchronized void put(int key, int value) {
if (map.containsKey(key)) {
map.get(key).value = value;
updateNode(map.get(key));
} else {
Node node = new Node(key, value);
map.put(key, node);
addNodeToFirst(node);
if (count > capacity) {
map.remove(tail.pre.key);
removeNode(tail.pre);
}
}
}
public synchronized void resize(int newCapacity) {
this.capacity = newCapacity;
while (count > capacity) {
Node toRemove = tail.pre;
map.remove(toRemove.key);
removeNode(toRemove);
}
}