题意
设计一个 LRUCache 的算法,什么是 LRU ,可以参考:LRU
思路
使用
Hash
+ 双向链表,主要是链表的删除和添加操作,链表头为新加入的任务,链表尾为最近最久未被使用的任务.
当新来一个任务之后,查看
Hash
表中时候存在:
- 如果存在,将此任务置于链表的头结点,操作为:先删除链表中的此任务,然后将此任务重新加入链表
- 如果不存在,说明需要删除链表中一个任务,那么删除尾节点.
PS :应该使用一个变量来记录当前链表中的任务数,最初的时候我使用判断 map.size() 来判断,但是会出现未知的错误,改用变量记录就好了.
代码
class linkList {
public:
int key;
int value;
linkList *next;
linkList *pre;
linkList(int k, int val) {
this->key = k;
this->value = val;
}
};
class LRUCache {
public:
map<int, linkList *>mp;
int maxSize;
int cnt;
linkList *headNode = NULL;
linkList *endNode = NULL;
LRUCache(int capacity) {
maxSize = capacity;
cnt = 0;
headNode = new linkList(0, 0);
endNode = new linkList(0, 0);
headNode->next = endNode;
headNode->pre = NULL;
endNode->next = NULL;
endNode->pre = headNode;
}
int get(int key) {
if (mp[key] != NULL) {
linkList *node = mp[key];
deleteNode(node);
addNode(node);
return node->value;
}
return -1;
}
void put(int key, int value) {
if (mp[key] != NULL) {
linkList *node = mp[key];
node->value = value;
deleteNode(node);
addNode(node);
} else {
linkList *node = new linkList(key, value);
mp[key] = node;
if (cnt < maxSize) {
addNode(node);
cnt++;
} else {
mp.erase(endNode->pre->key);
deleteNode(endNode->pre);
addNode(node);
}
}
}
void deleteNode(linkList *node) {
node->pre->next = node->next;
node->next->pre = node->pre;
}
void addNode(linkList *node) {
headNode->next->pre = node;
node->next = headNode->next;
node->pre = headNode;
headNode->next = node;
}
};