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
| class LRUCache {
private static class Node { private final int key; private int val; private Node prev; private Node next;
public Node(int key, int val) { this.key = key; this.val = val; } }
private final int capacity; private final Map<Integer, Node> cache; private final Node dummyHead; private final Node dummyTail;
public LRUCache(int capacity) { this.capacity = capacity; this.cache = new HashMap<>(); this.dummyHead = new Node(-1, -1); this.dummyTail = new Node(-1, -1); this.dummyHead.next = this.dummyTail; this.dummyTail.prev = this.dummyHead; } public int get(int key) { Node node = cache.get(key); if (node == null) { return -1; }
moveToHead(node); return node.val; }
private void removeNode(Node node) { Node prev = node.prev, next = node.next; prev.next = next; next.prev = prev; node.prev = null; node.next = null; }
private void addToHead(Node node) { Node head = dummyHead.next; dummyHead.next = node; head.prev = node; node.prev = dummyHead; node.next = head; }
private void moveToHead(Node node) { removeNode(node); addToHead(node); } public void put(int key, int value) { if (capacity == 0) { return; }
Node node = cache.get(key); if (node != null) { node.val = value; moveToHead(node); return; }
node = new Node(key, value); cache.put(key, node); addToHead(node);
if (cache.size() > capacity) { Node tail = dummyTail.prev; cache.remove(tail.key); removeNode(tail); } } }
|
注意是双向链表,移动节点时需要注意修改前后两个节点的指针,注意 map 与链表需要同步修改。
References
146. LRU Cache
面试题 16.25. LRU 缓存
剑指 Offer II 031. 最近最少使用缓存