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

提示:

  • 1 <= capacity <= 3000
  • 0 <= key <= 10000
  • 0 <= value <= 105
  • 最多调用 2 * 105 次 get 和 put
cpp 复制代码
class LRUCache {
public:
	LRUCache(int capacity) {
		m_capacity = capacity;
	}

	int get(int key) {
		if (!key2node.count(key))  return -1;
		//将cache中从key2node[key]开始指导cache末尾的元素移动到cache.begin前
		cache.splice(cache.begin(), cache, key2node[key]);
		return key2node[key]->second;
	}

	void put(int key, int value) {
		//存在,则擦除实际存储元素
		if (key2node.count(key)) cache.erase(key2node[key]);
		//检查当前是否达到的最大容量,如果是,则擦除最近最少使用的尾部元素,同时清除存储的元素
		if (cache.size()==m_capacity){
			key2node.erase(cache.back().first);
			cache.pop_back();
		}
		//插入元素
		cache.push_front({ key,value });
		//更新最近使用的元素
		key2node[key] = cache.begin();
	}
private:
	int m_capacity;
	//key2node哈希表,key映射一个迭代器,指向cache中{ key,value }
	unordered_map<int, list<pair<int ,int>>::iterator> key2node;
	//cache双向链表,保存{ key,value }
	list<pair<int, int>> cache;
};
相关推荐
大陈子编程12 分钟前
C++ 背包九讲:从入门到精通的动态规划专题
开发语言·c++·动态规划
凤山老林26 分钟前
授权模型只会RBAC?深入 ABAC 授权模型,实现权限判断做成策略引擎
大数据·数据库·算法
starzy199026 分钟前
KafkaProducer 源码深度剖析:支撑高吞吐的数据结构设计
大数据·数据结构·kafka
海绵宝宝转agent1 小时前
2026-10-21学习笔记
笔记·学习·算法
Dxy12393102161 小时前
ShardingSphere 自定义分片算法:BINARY(16) UUIDv7 哈希分片实现
算法·哈希算法
y1su1 小时前
Leetcode 链表,树,回溯 模板
java·leetcode·链表
2301_777998344 小时前
ARP协议进阶:ARP缓存、RARP与ARP欺骗原理解析
linux·服务器·网络·网络协议·缓存
罗湖老棍子12 小时前
【例 1】Sightseeing Trip(信息学奥赛一本通- P1494)(洛谷-P10927)
数据结构·算法·图论·最短路·floyd·最小环
文丑颜不良啊13 小时前
LeetCode201~225题目解析
java·leetcode
努力实干13 小时前
面向对象设计原则——C++
开发语言·c++·数码相机