双链表+map 实现。所有数据存在链表里,map里存key到Node*的映射。注意当删除时除了要从链表尾部删除节点外,还要map.erase(it)。Node里也要有key,因为为了删除时方便找到it。
#include <map>
using namespace std;
class Node {
public:
int key;
int val;
Node* prev;
Node* next;
Node(int _key, int _val) {
key = _key;
val = _val;
prev = NULL;
next = NULL;
}
};
class LRUCache{
public:
LRUCache(int _capacity) {
capacity = _capacity;
head = new Node(-1, -1);
tail = new Node(-1, -1);
head->next = tail;
tail->prev = head;
mp.clear();
size = 0;
}
int get(int key) {
if (mp.find(key) == mp.end()) { // not found
return -1;
}
else { // found
Node* cur = mp.find(key)->second;
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
moveToFirst(cur);
return cur->val;
}
}
void set(int key, int value) {
if (capacity == 0) return;
if (mp.find(key) == mp.end()) { // not found
if (size >= capacity) {
// remove last one
Node* deltmp = tail->prev;
deltmp->prev->next = tail;
tail->prev = deltmp->prev;
unordered_map<int, Node*>::iterator it = mp.find(deltmp->key);
mp.erase(it);
delete deltmp;
size--;
}
Node* addtmp = new Node(key, value);
moveToFirst(addtmp);
mp[key] = addtmp;
size++;
}
else { // found
Node* cur = mp.find(key)->second;
cur->val = value;
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
moveToFirst(cur);
}
}
private:
unordered_map<int, Node*> mp;
int capacity = 0;
int size = 0;
Node* head = NULL;
Node* tail = NULL;
void moveToFirst(Node* cur) {
cur->next = head->next;
cur->prev = cur->next->prev;
head->next = cur;
cur->next->prev = cur;
}
};
Python3,hashmap+双链表
要注意moveToHead的时候,要先将节点从前后摘除,在放到首位
class LRUCache:
def __init__(self, capacity: int):
self.hashmap = {}
self.capacity = capacity
self.dummyHead = Node(0, 0)
self.dummyTail = Node(0, 0)
self.dummyHead.next = self.dummyTail
self.dummyTail.prev = self.dummyHead
def get(self, key: int) -> int:
if key not in self.hashmap:
return -1
self.moveToHead(key)
return self.hashmap[key].val
def moveToHead(self, key):
node = self.hashmap[key]
nodeNext = node.next
nodePrev = node.prev
nodeNext.prev = nodePrev
nodePrev.next = nodeNext
headNext = self.dummyHead.next
self.dummyHead.next = node
node.prev = self.dummyHead
node.next = headNext
headNext.prev = node
def put(self, key: int, value: int) -> None:
if key in self.hashmap:
self.hashmap[key].val = value
self.moveToHead(key)
else:
self.hashmap[key] = Node(key, value)
node = self.hashmap[key]
node.next = self.dummyHead.next
self.dummyHead.next.prev = node
node.prev = self.dummyHead
self.dummyHead.next = node
# if full, remove tail
if len(self.hashmap) > self.capacity:
tail = self.dummyTail.prev
prev = tail.prev
prev.next = self.dummyTail
self.dummyTail.prev = prev
del self.hashmap[tail.key]
class Node:
def __init__(self, key:int, val: int):
self.key = key
self.val = val
self.next = None
self.prev = None
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)