当前位置:网站首页>力扣146题:LRU缓存
力扣146题:LRU缓存
2022-07-24 04:31:00 【瀛台夜雪】
力扣146题:LRU缓存
题目描述
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
输入输出样例
输入
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]
解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4
解法一,自定义双链表
//自定义双链表
struct DLinkedNode{
//存放键值
int key;
int value;
//定义头指针和尾指针
DLinkedNode *prev;
DLinkedNode *next;
//定义初始化函数
DLinkedNode():key(0),value(0),prev(nullptr),next(nullptr){
}
DLinkedNode(int keys,int values):key(keys),value(values),prev(nullptr),next(nullptr){
}
};
class LRUCache{
//public 存函数
//private 存放变量
private:
//建立hash表,表中存放 键key 和结点 ,通过对键的查找可以查找到对应的结点
unordered_map<int,DLinkedNode*>cache;
//定义头节点和尾结点
DLinkedNode *head;
DLinkedNode *tail;
int size;
int capacity;
public:
//一旦需要 key 和 value 肯定是 hash表
//要求:1.需要能随机访问 2.能够把数据插入头部或尾部
//使用hash表跟双向链表维护所有在缓冲中的键值对
//双向链表,按照顺序存储键值对,头部是最近使用,尾部是最久未使用
//哈希表,缓存数据键映射到链表中的位置
//构造函数
//初始化变量
LRUCache(int capa)
{
capacity=capa;
size=0;
//构建双链表结点的头指针和尾指针的指向关系
head=new DLinkedNode();
tail=new DLinkedNode();
head->next=tail;
tail->prev=head;
}
//显示数据
//首先判断数据是否存在,通过hash查找结点在双向链表中的位置,并移动到链表头部
int get(int key)
{
//如果键key在hash表中不存在则返回-1
if(!cache.count(key))
{
// cout<<-1<<endl;
return -1;
}
//若键key存在,则通过hash表进行定位,并将其移动到hash表的头部
DLinkedNode *node=cache[key];
//将结点移动到头节点
moveToHead(node);
// cout<<node->value<<endl;
return node->value;
}
//添加函数
//首先判断数据是否存在,若不存在,则新建一个结点,添加到双向链表中和哈希表中,并移动到首部
// 若存在,则先根据hash表进行定位,再将值更新为value,移动到链表的头部
void put(int key,int value)
{
//如果hash表的key不存在,则创建一个新的结点
if(!cache.count(key))
{
DLinkedNode *node=new DLinkedNode(key,value);
//将其值添加到hash表
cache[key]=node;
//并将结点添加到双向链表的头部
addToHead(node);
++size;
//如果hash表中数据的大小大于容量,则删除双向链表的最末尾的结点
if(size>capacity)
{
DLinkedNode *removed=removeTail();
//删除待删除的结点在hash表中对应的项
cache.erase(removed->key);
//删除结点 避免内存泄漏
delete removed;
--size;
}
}
//如果key在hash表中存在,首先通过hash表的定位,再修改value,并且移动到头部
else{
DLinkedNode*node=cache[key];
node->value=value;
moveToHead(node);
}
}
//将结点从当前位置挪出去
void removeNode(DLinkedNode *node)
{
node->prev->next=node->next;
node->next->prev=node->prev;
}
void addToHead(DLinkedNode *node)
{
node->prev=head;
node->next=head->next;
head->next->prev=node;
head->next=node;
}
//删除双向链表的尾结点
DLinkedNode * removeTail()
{
DLinkedNode *node=tail->prev;
removeNode(node);
return node;
}
//首先需要将当前结点从当前位置移除出去
//在将当前结点添加到链表的头部
void moveToHead(DLinkedNode *node)
{
removeNode(node);
addToHead(node);
}
};
解法二:使用链表的迭代器
//使用简便版本的LRUCache
class LRUCache2
{
private:
int capacity;
list<pair<int,int>>cache;
//定义hash表存储键和链表
unordered_map<int,list<pair<int,int>>::iterator>map;
public:
LRUCache2(int cap)
{
capacity=cap;
}
int get(int key)
{
if(!map.count(key))
{
cout<<-1<<endl;
return -1;
}
//key指向的结点
auto key_value=*map[key];
//找到指定的结点,删除当前结点,并将结点插入到链表的头部
cache.erase(map[key]);
cache.push_front(key_value);
map[key]=cache.begin();
//返回当前结点的值
cout<<key_value.second<<endl;
return key_value.second;
}
void put(int key,int value)
{
//如果hash表中不包含key
if(!map.count(key))
{
//hash中的长度刚好等于capacity长度
//将最久的删除
if(cache.size()==capacity)
{
map.erase(cache.back().first);
cache.pop_back();
}
}
//如果存在则将当前的结点先删除
else{
cache.erase(map[key]);
}
//插入头节点
cache.push_front({
key,value});
map[key]=cache.begin();
}
};
边栏推荐
- How to change the direction of this gracefully
- [essay] goodbye to Internet Explorer, and the mark of an era will disappear
- Qt5.14_MinGW/MSVC下实现VS2019面板自由拖拽组合功能
- Chapter III query processing of PostgreSQL Guide - Insider exploration
- How does the trend chart of spot silver change?
- An online accident, I suddenly realized the essence of asynchrony
- Jinglianwen technology provides 3D point cloud image annotation service
- Application scenarios and schemes of common mechanical equipment safety virtual simulation system
- MOS cameraization and digitization "includes designation (contro. skilled
- CONDA common commands
猜你喜欢

Codeforces Round #807 (Div. 2) A - D

iPhone手机绑定163邮箱解决方案

一次 svchost.exe 进程占用大量网络带宽的排查

The second anniversary of opengauss' open source, cracking the pain point of database ecology

postgresql源码学习(32)—— 检查点④-核心函数CreateCheckPoint

Write a search box with search tips

C语言基础学习笔记

C语言经典习题之猴子吃桃问题
[hope to answer] the data cannot be synchronized correctly
![[cornerstone of high concurrency] multithreading, daemon thread, thread safety, thread synchronization, mutual exclusion](/img/24/16cfb44dde056f4b91cdb1de2e9566.png)
[cornerstone of high concurrency] multithreading, daemon thread, thread safety, thread synchronization, mutual exclusion
随机推荐
Application scenarios and schemes of common mechanical equipment safety virtual simulation system
Merge sort
An online accident, I suddenly realized the essence of asynchrony
Traversal of binary tree
64 attention mechanism 10 chapters
BGP notes (II)
Redis sentinel mode, master node check script
Particle Designer:粒子效果制作器,生成plist文件并在工程中正常使用
【C语言】程序环境和预处理操作
Robustness evaluation of commercial in vivo detection platform
数组力扣(持续更新)
Smart people's game improvement: Chapter 3 Lesson 3 example: the secret of prime
Teacher qiniu said is the VIP account opened for you safe?
How about opening an account for Guotai Junan Securities? Is it safe
[JS] save the string as a file to the local (.Txt,.Json,.Md...)
Ambire wallet opens twitter spaces series
Live video | 37 how to use starrocks to realize user portrait analysis in mobile games
Jinglianwen technology provides 3D point cloud image annotation service
你有多久没有换新手机了?
What is the general family of programmers working in first tier cities?