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 {public : LRUCache(int capacity): capacity(capacity), head(new Node()), tail(new Node()) { head->post = tail; head->prev = nullptr ; tail->prev = head; tail->post = nullptr ; } int get (int key) { if (cache.find(key) != cache.end()) { moveNodeToHead(cache[key]); return cache[key]->val; } else return -1 ; } void put (int key, int value) { if (cache.find(key) == cache.end()) { if (cache.size() > capacity - 1 ) cache.erase(removeTailNode()); Node* node = new Node(key, value); addNodeToHead(node); cache[key] = node; }else { auto node = cache[key]; if (node->val != value) node->val = value; moveNodeToHead(node); } } private : struct Node { int key; int val; Node* prev; Node* post; Node() = default ; Node(int key, int val): key(key), val(val) {} }; void removeNode (Node* node) { node->prev->post = node->post; node->post->prev = node->prev; } void addNodeToHead (Node* node) { node->prev = head; node->post = head->post; head->post = node; node->post->prev = node; } void moveNodeToHead (Node* node) { removeNode(node); addNodeToHead(node); } int removeTailNode () { auto node = tail->prev; tail->prev = node->prev; tail->prev->post = tail; auto key = node->key; delete node; return key; } Node* head; Node* tail; int capacity; unordered_map <int , Node*> cache; };
使用doubleLinkedList是因为在删除时候需要操作前面的元素,因此DoublelinkedList可以实现O(1)的删除操作,而SingleLinkedList就需要O(n) 总体思路是访问过的移动到第一位,而最少访问的放在最后,如果新进来的时候缓存满了,那么就释放掉最后一位。