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;
};
相关推荐
SHARK_pssm1 天前
【数据结构——树与堆】
c语言·数据结构·经验分享·笔记
blueman88881 天前
VS2022 切换定义(F12 / Go to Definition)反应慢
c++·visual studio
bIo7lyA8v1 天前
算法可视化对教学与调试效率的影响分析的技术8
算法
凡人叶枫1 天前
Effective C++ 条款35:考虑 virtual 函数以外的其他选择
java·c++·spring
郝学胜-神的一滴1 天前
CMake 017:彩色日志输出实战
linux·c语言·开发语言·c++·软件工程·软件构建·cmake
hunterkkk(c++)1 天前
优先队列启发式最短路径快速算法(优化SPFA)-HEAP_SPFA算法
算法
SiliconGazer1 天前
第15届国赛满分代码解析(下)—— 运动轨迹算法、按键交互与完整状态机
算法·状态机·stc15f2k60s2·浮点运算·蓝桥杯国赛·运动轨迹、·向量分解
Navigator_Z1 天前
LeetCode //C - 1096. Brace Expansion II
c语言·算法·leetcode
luj_17681 天前
FreeDOS vs MS-DOS PC-DOS 对比解析
服务器·c语言·开发语言·经验分享·算法
RH2312111 天前
2026.6.10 数据结构 二叉树
数据结构