文章目录

  • 1. 题目信息
  • 2. 解题
    • 2.1 手动实现list
    • 2.2 使用内置list

1. 题目信息

运用你所掌握的数据结构,设计和实现一个 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/lru-cache
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

  • 类似题目:LeetCode 460. LFU缓存

2.1 手动实现list

要 put 和 get 方法的时间复杂度为 O(1),这个数据结构要:查找快,插入快,删除快,有顺序之分

  • 有顺序之分,区分最近使用的和久未使用的数据
  • 容量满了要删除最后一个数据
  • 访问时要把数据插入到队头。

哈希表查找快,但数据无顺序
链表有顺序之分,插入删除快,但查找慢。
结合一下以上两者的优点。

  • LRU 缓存算法的核心数据结构就是哈希链表双向链表哈希表的组合体。

借一张图表示下哈希链表。

class Node
{public:int key, value;Node *prev, *next;Node(int k, int v):prev(NULL),next(NULL){key = k;value = v;}
};
class DoubleList
{Node *head, *tail;int len;
public:DoubleList():len(0){head = new Node(0,0);tail = new Node(0,0);head->next = tail;tail->prev = head;}void addAtHead(Node* newnode){newnode->next = head->next;newnode->prev = head;head->next->prev = newnode;head->next = newnode;len++;}void delNode(Node *del){del->prev->next = del->next;del->next->prev = del->prev;len--;}Node* delLast()//删除最后的节点,并返回该节点{if(tail->prev == head)return NULL;Node *last = tail->prev;delNode(last);return last;}int size(){return len;}};
class LRUCache {unordered_map<int, Node*> m;DoubleList cache;int cap;
public:LRUCache(int capacity) {cap = capacity;}int get(int key) {if(m.find(key) == m.end())return -1;int val = m[key]->value;put(key, val);return val;}void put(int key, int value) {Node *newnode = new Node(key,value);if(m.find(key) != m.end())//找到节点,移至前面{cache.delNode(m[key]);cache.addAtHead(newnode);m[key] = newnode;}else//没找到key{if(cap == cache.size()){Node *last = cache.delLast();m.erase(last->key);}cache.addAtHead(newnode);m[key] = newnode;}}
};/*** 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);*/

2.2 使用内置list

class LRUCache {list<int> cache;int cap;unordered_map<int,int> kv;unordered_map<int,list<int>::iterator> kPos;
public:LRUCache(int capacity) {cap = capacity;}int get(int key) {if(!kv.count(key))return -1;put(key,kv[key]);return kv[key];}void put(int key, int value) {if(kv.count(key)){cache.erase(kPos[key]);cache.push_front(key);kPos[key] = cache.begin();kv[key] = value;}else{if(cap == cache.size()){int lastkey = cache.back();cache.pop_back();kv.erase(lastkey);}kv[key] = value;cache.push_front(key);kPos[key] = cache.begin();}}
};

LeetCode 146. LRU缓存机制(哈希链表)相关推荐

  1. Leetcode 146. LRU缓存机制【哈希表 [哈希表存储每个元素在双向链表中的指针]+双向链表】

    文章目录 问题描述 解题报告 实验代码 参考资料 问题描述 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . ...

  2. Java实现 LeetCode 146 LRU缓存机制

    146. LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...

  3. LeetCode —— 146. LRU缓存机制(Python)

    运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果关键字 (key) 存 ...

  4. C++实现LRU算法(LeetCode 146 LRU缓存机制)

    LRU算法: LRU算法(Least Recently Used)是一种缓存淘汰策略,最近使用的数据是有用的, 如果缓存满了,删除最久没用过的数据 LRU算法描述: (1)设置缓存大小 (2)get: ...

  5. [leetcode]146. LRU缓存机制

    1.LRU(最近最少使用)缓存机制: https://baike.baidu.com/item/LRU/1269842?fr=aladdin 2.用到的数据结构: struct Value {int ...

  6. Leetcode 146. LRU缓存机制 解题思路及C++实现

    解题思路: 使用一个双向链表存储最常使用的key value对,最近使用的元素放在链表的表头,链表中最后一个元素是使用频率最低的元素.同时,使用一个map来记录对应的<key,<key, ...

  7. Leetcode 146. LRU 缓存机制

    原题链接 题解:双链表+哈希表 class LRUCache { public:struct Node {int key, val;Node *left, *right;Node(int _key, ...

  8. LeetCode 146. LRU 缓存

    文章目录 一.题目 1.题目描述 2.基础框架 3.原题链接 二.解题报告 1.思路分析 2.时间复杂度 3.代码详解 1)定义 2)初始化 3)值的插入 4)值的获取 三.本题小知识 四.加群须知 ...

  9. 146. LRU 缓存机制

    146. LRU 缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 . 实现 LRUCache 类: LRUCache(int capacity) 以正整数作为容量 ...

最新文章

  1. [python+nltk] 自然语言处理简单介绍和NLTK坏境配置及入门知识(一)
  2. 德国布线牛到不行?今天带你看看咱们中国的!
  3. 判断一个指针有没有free_Free Code Camp的每个人现在都有一个档案袋
  4. linux java串口读写权限_解决linux下java读取串口之权限问题 No permission to create lock file. | 学步园...
  5. paip.ecshop邮件模板修改一个密码找回 一个留言回复
  6. 【阿朱一帖看尽】2014年BAT到底干了些什么
  7. java常用框架集合
  8. 建造者2全部岛屿_勇者斗恶龙建造者2全流程攻略介绍 通关流程攻略分享 蒙佐拉岛-游侠网...
  9. matlab编写erf函数
  10. 小米汽车VS苹果汽车,相同赛道不同逻辑
  11. 桔梗载药上浮 柴胡升于左 升麻生于右
  12. Datawhale组队学习周报(第025周)
  13. cadence SPB17.4 - allegro DRC - Physical - Maximum Neck Length
  14. stm32通过ESP8266连接互联网服务器,手机通过网页实现远程控制灯亮灭
  15. 每天一个小技巧——网易邮箱配置阿里云企业邮箱配置信息设置
  16. 连接HiveServer2的图形化工具SQuirrel和Dbeaver
  17. 简单(静态)工厂模式
  18. 362 敲击计数器
  19. NTP8835(30W内置DSP双通道D类音频功放芯片)
  20. k8s(一)、 1.9.0高可用集群本地离线部署记录

热门文章

  1. 基于C++中常见内存错误的总结
  2. pojo java_Java——POJO总结
  3. 分布式为什么使用Redis
  4. 微信开发学习日记(一):快速阅读5本书,掌握整体背景
  5. HDOJ 3415 Max Sum of Max-K-sub-sequence
  6. Cairngorm初学者入门教程 第六节--Cairngorm中Command利用Delegate与Service连接
  7. Ubuntu 10.10 下配置Telnet服务器
  8. 详解AST抽象语法树
  9. emailjava中怎么校验_Java使用注解实现参数统一校验功能
  10. timeSetEvent、回调函数、CCriticalSection