解题思路
这道题我们需要用hash加双向链表的方法来实现。
1.首先我们要定义一个双向链表的数据结构
struct doubleList {
int key, value;
doubleList* next;
doubleList* prev;
doubleList(): key(0), value(0), next(nullptr), prev(nullptr) {}
doubleList(int _key, int _value): key(_key), value(_value), next(nullptr), prev(nullptr) {}
};
2.进行初始化,定义一个伪头结点,伪尾结点,将头尾相连,并初始化需要用到的数据
unordered_map<int, doubleList*> hash;
doubleList* head = new doubleList();
doubleList* tail = new doubleList();
int size;
int capacity;
LRUCache(int _capacity) {
head->next = tail;
tail->prev = head;
size = 0;
capacity = _capacity;
}
既然我们要实现get方法就要将结点移动到头部(movetohead), put方法中我们除了要用到 movetohead, 还需要删除尾结点的操作(removetail), 添加头部(addhead)
addhead
void addhead(doubleList* node) {
doubleList* nexthead = head->next;
head->next = node;
nexthead->prev = node;
node->next = nexthead;
node->prev = head;
}
movetohead
实际上就是删除当前结点(removehead), 添加到头部
void removehead(doubleList* node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
void movetohead(doubleList* node) {
removehead(node);
addhead(node);
}
removetail
doubleList* removetail() {
doubleList* node = tail->prev;
removehead(node);
return node;
}
get
如果当前key值存在,则返回对应的value,并移到头部
否则返回-1
int get(int key) {
if(!hash.count(key))
return -1;
doubleList* node = hash[key];
movetohead(node);
return node->value;
}
put
如果当前结点不存在,则将该结点插入到头部,如果长度大于size,则删除尾部
如果存在,则将当前结点移动到头部并更新value
void put(int key, int value) {
if(!hash.count(key)) {
doubleList* node = new doubleList(key, value);
hash[key] = node;
addhead(node);
size++;
if(size > capacity) {
doubleList* node = removetail();
hash.erase(node->key);
size--;
}
}
else {
doubleList* node = hash[key];
node->value = value;
movetohead(node);
}
}