1. Hash+双向链表
1.1 Java实现:
public class LRUCache { class DLinkedNode { int key; int value; DLinkedNode pre; DLinkedNode next; DLinkedNode() { this.key = 0; this.value = 0; pre = null; next = null; } DLinkedNode(int key, int value) { this.key = key; this.value = value; pre = null; next = null; } } private ConcurrentMap<Integer, DLinkedNode> cache = new ConcurrentHashMap<Integer, DLinkedNode>(); private int size; private int capacity; private DLinkedNode head, tail; public LRUCache(int capacity) { this.size = 0; this.capacity = capacity; head = new DLinkedNode(); head.pre = null; tail = new DLinkedNode(); tail.next = null; head.next = tail; tail.pre = head; } public int get(String key) { DLinkedNode node = cache.get(key); if (node == null) { return -1; // should raise exception here. } moveToHead(node); return node.value; } public void put(int key, int value) { if (cache.containsKey(key)) { DLinkedNode node = cache.get(key); node.value = value; moveToHead(node); } else { DLinkedNode node = new DLinkedNode(key, value); cache.put(key, node); addToHead(node); ++size; if (size > capacity) { DLinkedNode tail = removeTail(); cache.remove(tail.key); size--; } } } private void moveToHead(DLinkedNode node) { removeNode(node); addToHead(node); } private void addToHead(DLinkedNode node) { node.pre = head; node.next = head.next; head.next.pre = node; head.next = node; } private void removeNode(DLinkedNode node) { DLinkedNode pre = node.pre; DLinkedNode next = node.next; pre.next = next; next.pre = pre; } private DLinkedNode removeTail() { DLinkedNode node = tail.pre; removeNode(node); return node; }}
1.2. C++实现
struct DLinkedListNode { DLinkedListNode *next, *prev; int key, val; DLinkedListNode() : key(0), val(0), next(nullptr), prev(nullptr) {} DLinkedListNode(int key, int val) : key(key), val(val), next(nullptr), prev(nullptr) {}};class LRUCache {private: unordered_map<int, DLinkedListNode *> cache; DLinkedListNode *head, *tail; int size, capacity;public: LRUCache(int capacity) : capacity(capacity), size(0) { head = new DLinkedListNode(); tail = new DLinkedListNode(); head->next = tail; tail->prev = head; } int get(int key) { if (!cache.count(key)) { return -1; } DLinkedListNode *node = cache[key]; moveToHead(node); return node->val; } void put(int key, int value) { if (!cache.count(key)) { DLinkedListNode *node = new DLinkedListNode(key, value); cache[key] = node; ++size; addToHead(node); if (size > capacity) { DLinkedListNode *node = removeTail(); cache.erase(node->key); delete node; size -= 1; } } else { DLinkedListNode *node = cache[key]; node->val = value; moveToHead(node); } } void moveToHead(DLinkedListNode *node) { removeNode(node); addToHead(node); } void removeNode(DLinkedListNode *node) {//1-->2-->3 node->prev->next = node->next; node->next->prev = node->prev; } void addToHead(DLinkedListNode *node) { node->prev = head; node->next = head->next;// head->next->prev = node; node->next->prev = node;// try one time; head->next = node; } DLinkedListNode *removeTail() { DLinkedListNode *node = tail->prev; removeNode(node); return node; }};