当前位置:网站首页>【7.3】146. LRU缓存机制
【7.3】146. LRU缓存机制
2022-07-03 14:19:00 【howtoloveyou】
方法:哈希表+双向链表
- 关键字:key,value对
- 模式识别:一旦出现键值对,就要想到哈希表
- 改变数据的访问时间:1 需要能够随机访问,2 需要能把该数据插到头部或者尾部
测试:
- 测试插入,包括溢出情况
- 测试更新,检查是否正确更新
- 测试读取,检测能否正确读取
hashmap+双向链表,复杂度分析:
- 时间复杂度:O1,哈希表定位O1,链表操作O1
- 空间复杂度:Oc
代码:
struct DLinkedNode {
int key, value;
DLinkedNode* prev;
DLinkedNode* next;
DLinkedNode(): key(0), value(0), prev(nullptr), next(nullptr) {
}
DLinkedNode(int _key, int _value): key(_key), value(_value), prev(nullptr), next(nullptr) {
}
};
class LRUCache {
private:
unordered_map<int, DLinkedNode*> cache;
DLinkedNode* head;
DLinkedNode* tail;
int size;
int capacity;
public:
LRUCache(int _capacity): capacity(_capacity), size(0) {
在初始化代码中的数据结构同时,初始化capacity和size两个参数
// 使用伪头部和伪尾部节点
head = new DLinkedNode(); 创建头部节点
tail = new DLinkedNode(); 创建尾部节点
head->next = tail; 头部-》尾部
tail->prev = head; 头部《-尾部
}
int get(int key) {
if (!cache.count(key)) {
如果没有则返回-1
return -1;
}
// 如果 key 存在,先通过哈希表定位,再移到头部
DLinkedNode* node = cache[key]; 通过哈希表定位再对节点进行操作
moveToHead(node); 这里将头部表示为最经常使用的元素
return node->value;
}
void put(int key, int value) {
if (!cache.count(key)) {
// 如果 key 不存在,创建一个新的节点
DLinkedNode* node = new DLinkedNode(key, value);
// 添加进哈希表
cache[key] = node;
// 添加至双向链表的头部
addToHead(node);
++size;
if (size > capacity) {
// 如果超出容量,删除双向链表的尾部节点
DLinkedNode* removed = removeTail();
// 删除哈希表中对应的项
cache.erase(removed->key);
// 防止内存泄漏
delete removed;
--size;
}
}
else {
// 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
DLinkedNode* node = cache[key];
node->value = value;
moveToHead(node);
}
}
void addToHead(DLinkedNode* node) {
node->prev = head;
node->next = head->next;
head->next->prev = node;
head->next = node;
}
void removeNode(DLinkedNode* node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
void moveToHead(DLinkedNode* node) {
removeNode(node);
addToHead(node);
}
DLinkedNode* removeTail() {
这里将最近没用过的节点提取出来,不会影响在哈希表中删除他的操作,因为他并没有消失
DLinkedNode* node = tail->prev;
removeNode(node);
return node;
}
};
边栏推荐
- 牛客网:过河卒
- Solution to failure or slow downloading of electron when electron uses electron builder to package
- Mongodb index
- String reverse order
- 必贝特医药冲刺科创板:年营收97万亏损1.37亿 拟募资20亿
- 战略、战术(和 OKR)
- concat和concat_ws()区别及group_concat()和repeat()函数的使用
- 7-17 crawling worms (break exercise)
- 7-20 print 99 formula table (format output)
- Learn to punch in today
猜你喜欢

concat和concat_ws()区别及group_concat()和repeat()函数的使用

泰凌冲刺科创板:拟募资13亿 国家大基金与小米长江是股东

Redis: operation command of string type data

X86 assembly language - Notes from real mode to protected mode

JS first summary

Exercise 6-2 using functions to sum special A-string sequences

使用并行可微模拟加速策略学习

Exercise 9-1 time conversion

Similarities and differences between Allegro, OrCAD, net alias, port, off page connector and how to select them

Leetcode(4)——寻找两个正序数组的中位数
随机推荐
SSH access control, blocking the IP when logging in repeatedly to prevent brute force cracking
Duet date picker (time plug-in that can manually enter the date)
Jiuyi cloud black free encryption free version source code
玖逸云黑免费无加密版本源码
Too many files with unapproved license
Exercise 9-1 time conversion
一文了解微分段应用场景与实现机制
NFT new opportunity, multimedia NFT aggregation platform okaleido will be launched soon
2021年区域赛ICPC沈阳站J-Luggage Lock(代码简洁)
中国锂电池电解液行业市场专项调研报告(2022版)
7-2 and then what time (15 minutes)
牛客网:过河卒
C language,%d% Difference between 2D%2d%02d
Add ZABBIX calculation type itemcalculated items
DDK for XP
Thread. Sleep and timeunit SECONDS. The difference between sleep
7-10 calculate salary
天图投资冲刺港股:资产管理规模249亿 投了小红书与奈雪
Redis: operation command of string type data
GRPC的四种数据流以及案例