leetcode LRU缓存机制(list+unordered_map)详细解析
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。
获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。
进阶:
你是否可以在 O(1) 时间复杂度内完成这两种操作?
示例:
LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 该操作会使得密钥 2 作废
cache.get(2); // 返回 -1 (未找到)
cache.put(4, 4); // 该操作会使得密钥 1 作废
cache.get(1); // 返回 -1 (未找到)
cache.get(3); // 返回 3
cache.get(4); // 返回 4
题解:
就是一种缓存淘汰策略。
计算机的缓存容量有限,如果缓存满了就要删除一些内容,给新内容腾位置。但问题是,删除哪些内容呢?我们肯定希望删掉哪些没什么用的缓存,而把有用的数据继续留在缓存里,方便之后继续使用。那么,什么样的数据,我们判定为「有用的」的数据呢?
LRU 缓存淘汰算法就是一种常用策略。LRU 的全称是 Least Recently Used,也就是说我们认为最近使用过的数据应该是是「有用的」,很久都没用过的数据应该是无用的,内存满了就优先删那些很久没用过的数据。
要让 put 和 get 方法的时间复杂度为 O(1)O(1),我们可以总结出 cache 这个数据结构必要的条件:查找快,插入快,删除快,有顺序之分。
因为显然 cache 必须有顺序之分,以区分最近使用的和久未使用的数据;而且我们要在 cache 中查找键是否已存在;如果容量满了要删除最后一个数据;每次访问还要把数据插入到队头。
那么,什么数据结构同时符合上述条件呢?哈希表查找快,但是数据无固定顺序;链表有顺序之分,插入删除快,但是查找慢。所以结合一下,形成一种新的数据结构:哈希链表。
参考代码:
class LRUCache {
private:
list<pair<int,int>> cache;
unordered_map<int, list<pair<int,int>>::iterator> ump;
int cap;
public:
LRUCache(int capacity) {
this->cap=capacity;
} int get(int key) {
auto it=ump.find(key);
if(it==ump.end()) return -;
pair<int,int> pv=*ump[key];
cache.erase(ump[key]);
cache.push_front(pv);
ump[key]=cache.begin(); return pv.second;
} void put(int key, int value) {
auto it=ump.find(key);
if(it==ump.end())
{
if(cache.size()==cap)
{
ump.erase(cache.back().first);
cache.pop_back();
}
cache.push_front(make_pair(key,value));
ump[key]=cache.begin();
}
else
{
cache.erase(ump[key]);
cache.push_front(make_pair(key,value));
ump[key]=cache.begin();
}
}
}; /**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/
C++
leetcode LRU缓存机制(list+unordered_map)详细解析的更多相关文章
- [Leetcode]146.LRU缓存机制
Leetcode难题,题目为: 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key ...
- Java实现 LeetCode 146 LRU缓存机制
146. LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...
- 【力扣】146. LRU缓存机制
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果关键字 (key) ...
- 常见面试题之操作系统中的LRU缓存机制实现
LRU缓存机制,全称Least Recently Used,字面意思就是最近最少使用,是一种缓存淘汰策略.换句话说,LRU机制就是认为最近使用的数据是有用的,很久没用过的数据是无用的,当内存满了就优先 ...
- Q200510-03-03 :LRU缓存机制
LRU缓存机制运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果密钥 ( ...
- Q200510-03-02: LRU缓存机制
问题: LRU缓存机制运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果 ...
- 力扣 - 146. LRU缓存机制
目录 题目 思路 代码 复杂度分析 题目 146. LRU缓存机制 思路 利用双链表和HashMap来解题 看到链表题目,我们可以使用头尾结点可以更好进行链表操作和边界判断等 还需要使用size变量来 ...
- 146. LRU 缓存机制 + 哈希表 + 自定义双向链表
146. LRU 缓存机制 LeetCode-146 题目描述 题解分析 java代码 package com.walegarrett.interview; /** * @Author WaleGar ...
- 【golang必备算法】 Letecode 146. LRU 缓存机制
力扣链接:146. LRU 缓存机制 思路:哈希表 + 双向链表 为什么必须要用双向链表? 因为我们需要删除操作.删除一个节点不光要得到该节点本身的指针,也需要操作其前驱节点的指针,而双向链表才能支持 ...
随机推荐
- Booth算法: 补码一位乘法公式推导与解析
以下讲解内容出自<计算机组成原理(第三版)>(清华大学出版社) 大二学生一只,我的计组老师比较划水,不讲公式推导,所以最近自己研究了下Booth算法的公式推导,希望能让同样在研究Booth ...
- Linux - Zip乱码问题
1. 可以通过解压后使用convmv来解决文件名乱码问题,通过iconv来解决文件内容的乱码问题 2. 用unar命令
- 细说unittest
一.unittest模块官方文档: https://docs.python.org/3/library/unittest.html 二.一张图看懂unittest: 三.Unittest主要方法属性: ...
- Mongodb 分片原理
1.主从mongodb 模式 类似,MySQL的主从配置 参照:https://blog.csdn.net/liusong0605/article/details/11551699 mongoDB有 ...
- 15. 深入解析Pod对象(二):使用进阶
15. 深入解析Pod对象(二):使用进阶 15.1 Projected Volume,投射数据卷 备注:Projected Volume 是 Kubernetes v1.11 之后的新特性 在 Ku ...
- map或者对象转换
map或者对象转换为具有相同字段的对象 List<Example> errorCodeExcelBeanList = JSONObject.parseArray(((JSONObject) ...
- JS vue 组件创建过程
https://www.jianshu.com/p/3504a1edba42 vue.js原生组件化开发(一)——组件开发基础 0.3472017.05.09 12:00:54字数 1120阅读 33 ...
- mcast_get_if函数
#include <errno.h> int sockfd_to_family(int); int mcast_get_if(int sockfd) { switch (sockfd_to ...
- 使用kibana或postman操作Elasticsearch的常用命令
前言服务器:CentOS-6.7 运行系统:windows10 JDK版本:1.8 Elasticsearch版本:5.6.6 插件:kibana.elasticsearch-head 工具:post ...
- GCC 升级
1.下载源码 wget ftp://ftp.gnu.org/gnu/gcc/gcc-4.8.5/gcc-4.8.5.tar.gz 2.下载依赖包编译安装 GCC 需要依赖 mpc,mpfr,gmp包. ...