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

LeetCode-146. LRU 缓存【设计 哈希表 链表 双向链表】

LeetCode-146. LRU 缓存【设计 哈希表 链表 双向链表】

  • 题目描述:
  • 解题思路一:双向链表,函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。一张图:
    • 知识点__slots__
  • 解题思路二:0
  • 解题思路三:0

题目描述:

请你设计并实现一个满足 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

解题思路一:双向链表,函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。一张图:

在这里插入图片描述

class Node:__slots__ = 'prev', 'next', 'key', 'value' # 提高访问属性的速度,并节省内存def __init__(self, key = 0, value = 0):self.key = keyself.value = valueclass LRUCache:def __init__(self, capacity: int):self.capacity = capacityself.dummy = Node() # 哨兵节点self.dummy.prev = self.dummyself.dummy.next = self.dummyself.key_to_node = dict()def get(self, key: int) -> int:node = self.get_node(key)return node.value if node else -1def put(self, key: int, value: int) -> None:node = self.get_node(key)if node: # 有这本书node.value = value # 更新 valuereturn self.key_to_node[key] = node = Node(key, value) # 新书self.push_front(node) # 放在最上面if len(self.key_to_node) > self.capacity: # 书太多了back_node = self.dummy.prevdel self.key_to_node[back_node.key] # 去掉最后一本书self.remove(back_node) # 去掉最后一本书def get_node(self, key: int) -> Optional[Node]:if key not in self.key_to_node: # 没有这本书return Nonenode = self.key_to_node[key] # 有这本书self.remove(node) # 把这本书抽出来self.push_front(node) # 放在最上面return nodedef remove(self, x: Node) -> None: # 删除一个节点(抽出一本书)x.prev.next = x.nextx.next.prev = x.prevdef push_front(self, x: Node) -> None: # 在链表头添加一个节点(把一本书放在最上面)x.prev = self.dummyx.next = self.dummy.nextx.prev.next = xx.next.prev = x# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)

时间复杂度:O(1)
空间复杂度:O(min(p,capacity)),其中 p 为 put 的调用次数。

知识点__slots__

slots 是 Python 中用于优化类的属性访问和节省内存的特殊属性。当你定义一个类时,通常每个实例对象都会有一个字典来存储其属性和方法,这种灵活性使得可以在运行时动态地添加、修改和删除属性。然而,对于某些需要高性能和节省内存的场景,这种灵活性可能会显得过于浪费资源。

slots 的作用就是告诉解释器:这个类的实例只能拥有 slots 中指定的属性,而不再使用字典来存储属性。这样做的好处有两个:

  1. 提高访问速度: 由于属性被限定在预定义的集合中,访问这些属性时不再需要通过字典查找,而是可以直接定位到它们,因此访问速度会更快。

  2. 节省内存: 没有了动态属性字典,实例对象所需的内存空间会更小。这在需要大量创建实例对象的场景中尤为有用,可以有效地节省内存资源。

使用 slots 时,你需要在类中定义一个 slots 属性,这个属性是一个字符串组成的元组,用于指定类的实例可以拥有的属性名称。例如:

class MyClass:__slots__ = ('attr1', 'attr2')def __init__(self, a, b):self.attr1 = aself.attr2 = b

在这个例子中,MyClass 的实例只能拥有 attr1 和 attr2 这两个属性,而不能拥有其他动态添加的属性。这样就提高了访问速度和节省了内存。

需要注意的是,使用 slots 也有一些限制:

  • 不能动态添加新的属性,因为 slots 指定了固定的属性集合。
  • 每个实例只能拥有 slots 中指定的属性,而不能拥有其他属性。
  • 继承时如果子类定义了 slots,则父类的 slots 不会被继承。

因此,在需要优化属性访问速度和节省内存的情况下,可以考虑使用 slots

解题思路二:0


时间复杂度:O(n)
空间复杂度:O(n)

解题思路三:0


时间复杂度:O(n)
空间复杂度:O(n)

相关文章:

LeetCode-146. LRU 缓存【设计 哈希表 链表 双向链表】

LeetCode-146. LRU 缓存【设计 哈希表 链表 双向链表】 题目描述&#xff1a;解题思路一&#xff1a;双向链表&#xff0c;函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。一张图&#xff1a;知识点__slots__ 解题思路二&#xff1a;0解题思路三&#xff1a;0 题目描述&am…...

如何在Python中import其他文件的实时值

在A.py中加入变量TEST_A0后&#xff0c;可以通过不同的方式在B.py中调用该变量。下面是对两种方式的介绍&#xff1a; 使用from A import TEST_A调用TEST_A&#xff1a; 这种方式是直接将A.py中的TEST_A变量导入到B.py中&#xff0c;可以直接使用TEST_A变量&#xff0c;而不需…...

NumPy进阶(二)

2. NumPy进阶(二) 2.1 Numpy数组操作 2.1.1 添加元素 numpy.append 函数在数组的末尾添加值。 追加操作会分配整个数组&#xff0c;并把原来的数组复制到新数组中 注意&#xff1a; 插入的维度要保证所有数组的长度是相同的如果没有指定轴&#xff0c;数组会被扁平处理 ndarr…...

计算机专业,不擅长打代码,考研该怎么选择?

考研其实和你的代码能力关系不大 所以在选学校以前可以看看有哪些学校复试是要求上机撸代码的&#xff0c;可能会要求比较严 初试真的不用担心代码问题&#xff0c;我也是基本零编程能力就开始备考考研的... 本人双非科班出身备考408成功上岸&#xff0c;在这里也想给想考40…...

SQL Server的详细使用教程

安装SQL Server 下载SQL Server 安装程序运行安装程序,选择"基本"安装类型在"实例配置"页面,将实例命名为"SQLServerTest"在"服务器配置"页面,选择"NT服务\系统"作为启动账户完成其他设置,然后安装SQL Server 连接SQL Serve…...

挑错罐头=“害猫”!猫咪主食罐到底应该怎么选?

猫咪罐头已经成为众多猫奴们的喂养首选。它富含水分&#xff0c;有助于猫咪保持良好的泌尿系统健康&#xff0c;尤其对于那些不太喜欢饮水的猫咪来说&#xff0c;罐头无疑是补充水分的理想方式。罐头的口感极佳&#xff0c;肉质细腻&#xff0c;能够激发猫咪的食欲&#xff0c;…...

43---SATA电路设计

视频链接 SATA硬件电路设计01_哔哩哔哩_bilibili SATA电路设计 1、硬盘分类 硬盘按照原理可以分为机械硬盘&#xff08;HDD&#xff09;、固态硬盘&#xff08;SSD&#xff09;以及混合硬盘&#xff08;SSHD&#xff09;三类。 1.1、机械硬盘&#xff08;HDD&#xff09; …...

think:该写什么样的blog

前言 好久没更新blog&#xff0c;简单写点东西。随着chatgpt为首的大模型兴起&#xff0c;发现周边的很多程序员逐步减少使用google&#xff0c;Stack Overflow等搜索常见的问题&#xff0c;csdn流量估计也会受到不小的影响。chatgpt的下限不低&#xff0c;从简单的语法查询到…...

【APUE】网络socket编程温度采集智能存储与上报项目技术------多路复用

作者简介&#xff1a; 一个平凡而乐于分享的小比特&#xff0c;中南民族大学通信工程专业研究生在读&#xff0c;研究方向无线联邦学习 擅长领域&#xff1a;驱动开发&#xff0c;嵌入式软件开发&#xff0c;BSP开发 作者主页&#xff1a;一个平凡而乐于分享的小比特的个人主页…...

GitHub 仓库 (repository) Pulse - Contributors - Network

GitHub 仓库 [repository] Pulse - Contributors - Network 1. Pulse2. Contributors3. NetworkReferences 1. Pulse 显示该仓库最近的活动信息。该仓库中的软件是无人问津&#xff0c;还是在火热地开发之中&#xff0c;从这里可以一目了然。 2. Contributors 显示对该仓库进…...

C语言题目:阶乘数列求和(函数)

题目描述 输入一个正数x和一个正整数n&#xff0c;求下列算式的值。要求定义两个调用函数&#xff1a;fact(n)计算n的阶乘&#xff1b;mypow(x,n)计算x的n次幂&#xff08;即xn&#xff09;&#xff0c;两个函数的返回值类型是double。 x - x2/2! x3/3! ... (-1)n-1xn/n! …...

Unity与CocosCreator对比学习二

一、锚点与适配 1.在Creator中 适配通过锚点、位置和Widget达到适配目的&#xff1b;锚点是节点在其父节点坐标系中坐标对其点&#xff0c;其x,y范围在[0, 1]之间&#xff1b; 锚点为(0, 0)时在节点自身的左下角&#xff0c;节点坐标指其左下角在父节点中的坐标&#xff1b;锚…...

01-Git 快速入门

https://learngitbranching.js.org/?localezh_CN在线练习git 1. Git 安装好Git以后, 先检查是否已经绑定了用户名和邮箱 git config --list再检查C:\Users\xxx.ssh 下是否存在 id_rsa.pub , 存在的话复制其内容到 GitHub 的 SSH KEY 中 没有这一步, PUSH操作的时候会报错:…...

Axure RP中的相关概念及高保真原型构建方法

1 Axure RP中概念介绍 对于构建高保真原型来说&#xff0c;需要知道事件&#xff08;Event&#xff09;、Case、Action等概念。Axure RP中给出这些概念&#xff0c;是为了方便原型的构建&#xff0c;尤其是高保真原型的构建。 事件&#xff08;Event&#xff09;是附着于控件…...

Ruoyi-vue-pro Vue + nginx 二级目录部署到云服务器

http://www.your-server.com/ 这是一级目录&#xff0c;由于项目多&#xff0c;一般会通过二级域名http://oa.your-server.com/或二级目录http://www.your-server.com/oa来发布&#xff0c;本篇记录一下二级目录发布。先看效果 1、router/index.js配置base export default new …...

leetcode2529--正整数和负整数的最大计数

1. 题意 给定有序数组&#xff0c;求其中正整数和负整数的计数最大值。 正整数和负整数的最大计数 2. 题解 2.1 遍历 直接判断 class Solution { public:int maximumCount(vector<int>& nums) {int neg 0;int pos 0;for (int num:nums) {if (!num)continue;i…...

使用YOLOv8训练自己的【目标检测】数据集

文章目录 1.收集数据集1.1 使用开源已标记数据集1.2 爬取网络图像1.3 自己拍摄数据集1.4 使用数据增强生成数据集1.5 使用算法合成图像 2.标注数据集2.1确认标注格式2.2 开始标注 3.划分数据集4.配置训练环境4.1获取代码4.2安装环境 5.训练模型5.1新建一个数据集yaml文件5.2预测…...

rust学习(recursive mutex 实现)

问题&#xff1a; 编写如下代码的时候出现死锁&#xff1a; pub fn test_double_lock() {let t Arc::new(Mutex::new(1));let t1 t.clone();let t2 t.clone();let h std::thread::spawn(move || {println!("hello trace1");let l1 t1.lock().unwrap();println…...

DasViewer可以添加照片到里面吗?点开就可以看照片?

DasViewer主要是三维模型浏览器&#xff0c;二维可以添加矢量和正射影像&#xff0c;航片暂不支持。 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑配置下,也能流畅的加载较大规模实景三维模型,提供方便…...

python蓝桥杯选数

文章目录 前言一、题意二、代码1.代码的实现2.读入数据 总结 前言 本题涉及到很多python中的知识点&#xff0c;比如combinations&#xff08;列表的组合&#xff09;应用&#xff0c;以及素数的判断 一、题意 已知 n 个整数 x1,x2,…,xn,以及一个整数 k&#xff08;k&#x…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...