[leetcode]LRU Cache
双链表+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)