当前位置:网站首页>【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;
}
};
边栏推荐
- Exercise 10-6 recursively find Fabonacci sequence
- Scroll detection, so that the content in the lower right corner is not displayed at the top of the page, but is displayed as the mouse slides
- js . Find the first palindrome string in the array
- JS Part 2
- Preliminary summary of structure
- 天图投资冲刺港股:资产管理规模249亿 投了小红书与奈雪
- fpga阻塞赋值和非阻塞赋值
- 超简单手机地图开发
- 关于回溯问题中的排列问题的思考(LeetCode46题与47题)
- How Facebook moves instagram from AWS to its own server
猜你喜欢

Programming language: the essence of type system

TS code automatically generates JS

牛客网:过河卒

Scroll detection of the navigation bar enables the navigation bar to slide and fix with no content

愉悦资本新双币基金近40亿元完成首次关账

Leetcode(4)——尋找兩個正序數組的中比特數

Eight sorts

x86汇编语言-从实模式到保护模式 笔记

Exercise 7-6 count capital consonants

好看、好用、强大的手写笔记软件综合评测:Notability、GoodNotes、MarginNote、随手写、Notes Writers、CollaNote、CollaNote、Prodrafts、Noteshelf、FlowUs、OneNote、苹果备忘录
随机推荐
Too many files with unapproved license
JS input number and standard digit number are compared. The problem of adding 0 to 0
Leetcode (4) - - trouver la médiane de deux tableaux ordonnés positifs
Exercise 6-2 using functions to sum special A-string sequences
7-11 calculation of residential water charges by sections
Learn to punch in today
etcd集群权限管理和账号密码使用
好看、好用、强大的手写笔记软件综合评测:Notability、GoodNotes、MarginNote、随手写、Notes Writers、CollaNote、CollaNote、Prodrafts、Noteshelf、FlowUs、OneNote、苹果备忘录
PCB中常用快捷键
NFT新的契机,多媒体NFT聚合平台OKALEIDO即将上线
Raft 协议
Sword finger offer 28 Symmetric binary tree
MongoDB索引
allegro,orcad, net alias,port,off-page connector之间的异同点和如何选取
一文了解微分段应用场景与实现机制
Exercise 7-6 count capital consonants
洛谷P5018 [NOIP2018 普及组] 对称二叉树 题解
x86汇编语言-从实模式到保护模式 笔记
7-28 monkeys choose King (Joseph problem)
Exercise 8-8 moving letters