当前位置: 首页 > news >正文

LRU 缓存 -- 哈希链表

相关题目
146. LRU 缓存

要让 put 和 get ⽅法的时间复杂度为 O(1),我们可以总结出 cache 这个数据结构必要的条件:
1、显然 cache 中的元素必须有时序,以区分最近使⽤的和久未使⽤的数据,当容量满了之后要删除最久未使⽤的那个元素腾位置。
2、我们要在 cache 中快速找某个 key 是否已存在并得到对应的 val。
3、每次访问 cache 中的某个 key,需要将这个元素变为最近使⽤的,也就是说 cache 要⽀持在任意位置快速插⼊和删除元素。

哈希表查找快,但是数据⽆固定顺序;链表有顺序之分,插⼊删除快,但是查找慢,所以结合⼆者的⻓处,可以形成⼀种新的数据结构:哈希链表 LinkedHashMap

在Python中,可以使用collections模块中的OrderedDict类来实现类似于Java中LinkedHashMap的功能。

本文最后还提供了一种 结合双向链表和哈希表的 从零开始的实现,供参考。

// 使用 LinkedHashMap 实现
class LRUCache {int cap;LinkedHashMap<Integer, Integer> cache = new LinkedHashMap<>();public LRUCache(int capacity) {this.cap = capacity;}public int get(int key) {if (!cache.containsKey(key)) {return -1;}// 将 key 变为最近使⽤makeRecently(key);return cache.get(key);}public void put(int key, int val) {if (cache.containsKey(key)) {// 修改 key 的值cache.put(key, val);// 将 key 变为最近使⽤makeRecently(key);return;}if (cache.size() >= this.cap) {// 链表头部就是最久未使⽤的 keyint oldestKey = cache.keySet().iterator().next();cache.remove(oldestKey);}// 将新的 key 添加链表尾部cache.put(key, val);}private void makeRecently(int key) {int val = cache.get(key);// 删除 key,重新插⼊到队尾cache.remove(key);cache.put(key, val);}
}
# 使用 OrderedDict 实现
from collections import OrderedDictclass LRUCache:def __init__(self, capacity: int):self.cc = capacityself.d = OrderedDict()def get(self, key: int) -> int:if key in self.d:self.d.move_to_end(key)return self.d[key]return -1def put(self, key: int, value: int) -> None:if key in self.d:del self.d[key]self.d[key] = valueif len(self.d) > self.cc:self.d.popitem(last=False)
# 手撸LRU算法,结合双向链表和哈希表,LinkedHashMap
# 先定义双向链表节点
class DoubleListNodeLRU:next, last = None, Nonedef __init__(self, k, v):self.k = kself.v = vclass NodeLRU:head, tail = None, Nonesize = Nonedef __init__(self):# head tail 为 头尾虚拟节点self.head = DoubleListNodeLRU(0, 0)self.tail = DoubleListNodeLRU(0, 0)self.head.next = self.tailself.tail.last = self.headself.size = 0# 链表尾部添加节点 时间 O(1)def addLast(self, x: DoubleListNodeLRU):x.last = self.tail.lastx.next = self.tailself.tail.last.next = xself.tail.last = xself.size += 1# 删除链表中的 x 节点(x ⼀定存在)# 由于是双链表且给的是⽬标Node节点,时间O(1)def remove(self, x: DoubleListNodeLRU):x.last.next = x.nextx.next.last = x.lastself.size -= 1# 删除链表中第⼀个节点,并返回该节点,时间 O(1)def removeFirst(self):if self.head.next == self.tail:return Nonefirst = self.head.nextself.remove(first)return firstclass LRUCache:def __init__(self, capacity: int):self.cap = capacity# key -> node(key, val)self.map = dict()self.cache = NodeLRU()# 将某个 key 提升为最近使⽤的def makeRecently(self, k):node = self.map.get(k)self.cache.remove(node)self.cache.addLast(node)# 添加最近使⽤的元素def addRecently(self, k, v):node = DoubleListNodeLRU(k, v)self.cache.addLast(node)self.map[k] = node# 删除某⼀个 keydef deletekey(self, k):node = self.map[k]self.map.pop(k)self.cache.remove(node)def removeLeastRecently(self):deleteNode = self.cache.removeFirst()deletekey = deleteNode.kself.map.pop(deletekey)def get(self, k):if k not in self.map:return -1self.makeRecently(k)return self.map.get(k).vdef put(self, k, v):if k in self.map:self.deletekey(k)self.addRecently(k, v)returnif self.cache.size == self.cap:self.removeLeastRecently()self.addRecently(k, v)
http://www.lryc.cn/news/184411.html

相关文章:

  • DWC数字世界大会先导论坛将于10月13日在宁波举办 | 数字技术赋能世界可持续发展
  • Springboot实现登录功能(token、redis、登录拦截器、全局异常处理)
  • AI工程化—— 如何让AI在企业多快好省的落地?
  • mysqld_multi测试
  • MDC方式实现简单链路追踪
  • Linux深度学习:除基本命令操作外的实用操作
  • app对接广告变现平台:影响app广告单价的4大因素
  • 【数字化转型】10大数字化转型能力成熟度模型01(IOMM)
  • 2023腾讯云轻量应用服务器和普通服务器有什么区别?
  • SSL证书是什么?1分钟get
  • 3D打印机升级killpper
  • 源码编译dotnetcore的runtime
  • 11个在线免费调整图像大小而不会降低质量工具
  • 聊聊机器的情感和意识
  • 职责链模式,非常容易被忽视的设计模式之一(设计模式与开发实践 P13)
  • 架构师选择题--计算机网络
  • 【图论】Linova and Kingdom—CF1336A
  • 【红日靶场】vulnstack3-完整渗透过程
  • 物联网通信技术课程作业资料(TPUNB技术)
  • [开源]研发管理项目,支持从需求到代码发布全过程全生命周期管理
  • 一文生成猫眼电影热榜词云
  • 监控脚本展示
  • 【重拾C语言】五、模块化程序设计——函数(定义、调用、参数传递、结果返回、函数原型;典例:打印字符图形、验证哥德巴赫猜想)
  • Unity实现设计模式——迭代器模式
  • 【数据结构与算法】之“堆”介绍
  • ncnn Fatal signal 11 (SIGSEGV) 使用GPU加速崩溃
  • 计算机考研 | 2018年 | 计算机组成原理真题
  • 用Configuration注解的方式写一个java过滤器的详细实例?
  • 基于Springboot实现旧物置换网站平台演示【项目源码+论文说明】分享
  • 想要精通算法和SQL的成长之路 - 存在重复元素