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;
};
相关推荐
某个默默无闻奋斗的人44 分钟前
三傻排序的比较(选择,冒泡,插入)
java·数据结构·算法
YxVoyager2 小时前
OpenGL学习笔记(六):Transformations 变换(变换矩阵、坐标系统、GLM库应用)
c++·笔记·图形渲染
黄雪超2 小时前
算法基础——一致性
大数据·算法·一致性
敲上瘾3 小时前
BFS(广度优先搜索)——搜索算法
数据结构·c++·算法·搜索引擎·宽度优先·图搜索算法
Captain823Jack3 小时前
【leetcode练习·二叉树拓展】归并排序详解及应用
算法·leetcode·职场和发展
查理零世3 小时前
【算法】回溯算法专题② ——组合型回溯 + 剪枝 python
python·算法·剪枝
酒酿泡芙12173 小时前
前端力扣刷题 | 6:hot100之 矩阵
前端·leetcode·矩阵
Chandler243 小时前
C++11 多线程 锁与条件变量:mutex、lock_guard、unique_lock 和 condition_variable
c++
JackieZhang.3 小时前
求水仙花数,提取算好,打表法。或者暴力解出来。
数据结构·算法
LUCIAZZZ4 小时前
Hot100之贪心算法
数据结构·算法·leetcode·贪心算法