学习对象初始化的方法
Node(int _key, int _value): key(_key), value(_value) {
head = new Node();
taile = new Node();
...
}
注意的几点,结构体定义结束后面+分号;
这道题主要考虑:双向链表、哈希表(unordered_map)
LRU类中成员变量有size、capacity、head、tail(虚拟头节点、虚拟尾节点)、unoredered_map<int, Node*>
在使用get时:
- 命中,将该节点移动至头部
- 未命中,返回-1 在使用put时:
- 之前存在:只需要将node的value修改,并将该nodemove至头部
- 之前不存在:new一个node节点,将该节点add至头部。同时size++,并需要考虑size是否超过即>capacity,超过则需要删除最后一个节点
以上重复的一些操作可写一个函数:例如moveToHead、removeNode、addToHead
其实moveToHead就是removeNode、addToHead加起来
struct Node {
int key;
int value;
Node* prev;
Node* next;
Node(): key(0), value(0), prev(nullptr), next(nullptr) {}
Node(int _key, int _value): key(_key), value(_value), prev(nullptr), next(nullptr) {}
};
class LRUCache {
private:
unordered_map<int, Node*> cache;
Node* head;
Node* tail;
int size;
int capacity;
public:
LRUCache(int _capacity): capacity(_capacity), size(0) {
head = new Node();
tail = new Node();
head->next = tail;
tail->prev = head;
}
int get(int key) {
auto it = cache.find(key);
// 未命中
if(it == cache.end()) {
return -1;
}
// 命中
Node* node = it->second;
moveToHead(node);
return node->value;
}
void put(int key, int value) {
auto it = cache.find(key);
// 之前不存在
if(it == cache.end()) {
// 创建一个node,并将该node添加至头部
Node* node = new Node(key, value);
cache[key] = node;
addToHead(node);
++size;
if(size > capacity) {
// 删除尾部节点
Node* tmp = tail->prev;
cache.erase(tmp->key);
tmp->prev->next = tail;
tail->prev = tmp->prev;
delete tmp;
--size;
}
}
// 之前存在
else {
Node* node = it->second;
node->value = value;
moveToHead(node);
}
}
void removeNode(Node* node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
void addToHead(Node* node) {
node->prev = head;
node->next = head->next;
head->next->prev = node;
head->next = node;
}
void moveToHead(Node* node) {
removeNode(node);
addToHead(node);
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/