Python算法题集_LRU 缓存
Python算法题集_LRU 缓存
- 题146:LRU 缓存
- 1. 示例说明
- 2. 题目解析
- - 题意分解
- - 优化思路
- - 测量工具
- 3. 代码展开
- 1) 标准求解【队列+字典】
- 2) 改进版一【有序字典】
- 3) 改进版二【双向链表+字典】
- 4. 最优算法
本文为Python算法题集之一的代码示例
题146:LRU 缓存
1. 示例说明
-
请你设计并实现一个满足 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 <= 30000 <= key <= 100000 <= value <= 105- 最多调用
2 * 105次get和put
2. 题目解析
- 题意分解
- 本题为设计一个整形缓存类,可以指定缓存大小
- 基本的设计思路是采用队列控制使用次序,字典进行缓存【哈希】
- 优化思路
-
通常优化:减少循环层次
-
通常优化:增加分支,减少计算集
-
通常优化:采用内置算法来提升计算速度
-
分析题目特点,分析最优解
-
可以考虑采用有序字典设计缓存类
-
可以考虑采用双向链表设计使用队列,缓存还是采用字典
-
- 测量工具
- 本地化测试说明:LeetCode网站测试运行时数据波动很大,因此需要本地化测试解决这个问题
CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块- 本题本地化超时测试用例自己生成,详见【最优算法章节】
3. 代码展开
1) 标准求解【队列+字典】
队列控制使用次序,字典保存键值对
勉强通关,超过05%
import CheckFuncPerf as cfpclass LRUCache_base:
def __init__(self, capacity):self.queue, self.dict, self.capacity, self.queuelen = [], {}, capacity, 0
def get(self, key):if key in self.queue:self.queue.remove(key)self.queue.append(key)return self.dict[key]else:return -1
def put(self, key, value):if key in self.queue:self.queue.remove(key)else:if self.queuelen == self.capacity:self.dict.pop(self.queue.pop(0))else:self.queuelen += 1self.queue.append(key)self.dict[key] = valutmpLRUCache = LRUCache_base(5)
result = cfp.getTimeMemoryStr(testLRUCache, tmpLRUCache, actions)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 testLRUCache 的运行时间为 561.12 ms;内存使用量为 4.00 KB 执行结果 = 99
2) 改进版一【有序字典】
采用有序字典【Python3.6之后支持】,同时支持使用顺序和保存键值对
性能卓越,超越93%
import CheckFuncPerf as cfpclass LRUCache_ext1:def __init__(self, capacity):self.data = dict()self.capacity = capacitydef get(self, key):keyval = self.data.get(key, -1)if keyval != -1:self.data.pop(key)self.data[key] = keyvalreturn keyvaldef put(self, key, value)if key in self.data:self.data.pop(key)self.data[key] = valueelse:if len(self.data) < self.capacity:self.data[key] = valueelse:firstpop = next(iter(self.data))self.data.pop(firstpop)self.data[key] = valuetmpLRUCache = LRUCache_ext1(5)
result = cfp.getTimeMemoryStr(testLRUCache, tmpLRUCache, actions)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 testLRUCache 的运行时间为 420.10 ms;内存使用量为 0.00 KB 执行结果 = 99
3) 改进版二【双向链表+字典】
采用双向链表维护使用顺序,字典保存键值对,要首先定义双向链表类
性能卓越,超过92%
import CheckFuncPerf as cfpclass ListNodeDouble:def __init__(self, key=None, value=None):self.key = keyself.value = valueself.prev = Noneself.next = None
class LRUCache_ext2:def __init__(self, capacity):self.capacity = capacityself.dict = {}self.head = ListNodeDouble()self.tail = ListNodeDouble()self.head.next = self.tailself.tail.prev = self.headdef move_to_tail(self, key):tmpnode = self.dict[key]tmpnode.prev.next = tmpnode.nexttmpnode.next.prev = tmpnode.prevtmpnode.prev = self.tail.prevtmpnode.next = self.tailself.tail.prev.next = tmpnodeself.tail.prev = tmpnodedef get(self, key: int):if key in self.dict:self.move_to_tail(key)result = self.dict.get(key, -1)if result == -1:return resultelse:return result.valuedef put(self, key, value):if key in self.dict:self.dict[key].value = valueself.move_to_tail(key)else:if len(self.dict) == self.capacity:self.dict.pop(self.head.next.key)self.head.next = self.head.next.nextself.head.next.prev = self.headnewkeyval = ListNodeDouble(key, value)self.dict[key] = newkeyvalnewkeyval.prev = self.tail.prevnewkeyval.next = self.tailself.tail.prev.next = newkeyvalself.tail.prev = newkeyvaltmpLRUCache = LRUCache_ext2(5)
result = cfp.getTimeMemoryStr(testLRUCache, tmpLRUCache, actions)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 运行结果
函数 testLRUCache 的运行时间为 787.18 ms;内存使用量为 0.00 KB 执行结果 = 99
4. 最优算法
根据本地日志分析,最优算法为第2种方式【有序字典】LRUCache_ext1
def testLRUCache(lrucache, actiions):for act in actiions:if len(act) > 1:lrucache.put(act[0], act[1])else:lrucache.get(act[0])return 99
import random
actions = []
iLen = 1000000
for iIdx in range(10):actions.append([iIdx, random.randint(1, 10)])
iturn = 0
for iIdx in range(iLen):if iturn >= 2:actions.append([random.randint(1,10)])else:actions.append([random.randint(1,10), random.randint(1, 1000)])iturn += 1if iturn >= 3:iturn = 0
tmpLRUCache = LRUCache_base(5)
result = cfp.getTimeMemoryStr(testLRUCache, tmpLRUCache, actions)
print(result['msg'], '执行结果 = {}'.format(result['result']))# 算法本地速度实测比较
函数 testLRUCache 的运行时间为 561.12 ms;内存使用量为 4.00 KB 执行结果 = 99
函数 testLRUCache 的运行时间为 420.10 ms;内存使用量为 0.00 KB 执行结果 = 99
函数 testLRUCache 的运行时间为 787.18 ms;内存使用量为 0.00 KB 执行结果 = 99
一日练,一日功,一日不练十日空
may the odds be ever in your favor ~
相关文章:
Python算法题集_LRU 缓存
Python算法题集_LRU 缓存 题146:LRU 缓存1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【队列字典】2) 改进版一【有序字典】3) 改进版二【双向链表字典】 4. 最优算法 本文为Python算法题集之一的代码示例 题146:LRU …...
局部加权回归
局部加权回归(Local Weighted Regression)是一种非参数回归方法,用于解决线性回归模型无法很好拟合非线性数据的问题。它通过给不同的样本赋予不同的权重,使得在拟合模型时更加关注靠近目标点附近的样本数据。 局部加权回归的基本…...
国内国外最好的数据恢复软件评测,哪种数据恢复软件最有效?
随着数字和商业格局在多个领域不断发展,变得更加依赖数据,威胁数据的努力也同样存在。 计算机病毒、勒索软件和恶意软件是导致数据丢失的主要威胁,可能会让您的组织陷入停机或严重影响您的工作效率。而解决这个问题的方法就是数据恢复。 什么…...
bugku 1
Flask_FileUpload 文件上传 先随便传个一句话木马 看看回显 果然不符合规定 而且发现改成图片什么的都不行 查看页面源代码,发现提示 那应该就要用python命令才行 试试ls 类型要改成图片 cat /flag 好像需要密码 bp爆破 根据提示,我们先抓包 爆破 …...
C++ bfs再探迷宫游戏(五十五)【第二篇】
今天我们用bfs解决迷宫游戏。 1.再探迷宫游戏 前面我们已经接触过了迷宫游戏,并且学会了如何使用 DFS 来解决迷宫最短路问题。用 DFS 求解迷宫最短路有一个很大的缺点,需要枚举所有可能的路径,读入的地图一旦很大,可能的搜索方案…...
【Spring原理进阶】SpringMVC调用链+JSP模板应用讲解
🎉🎉欢迎光临🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟特别推荐给大家我的最新专栏《Spring 狂野之旅:底层原理高级进阶》 🚀…...
23种计模式之Python/Go实现
目录 设计模式what?why?设计模式:设计模式也衍生出了很多的新的种类,不局限于这23种创建类设计模式(5种)结构类设计模式(7种)行为类设计模式(11种) 六大设计原则开闭原则里氏替换原…...
Qt可视化大屏布局
科技大屏现在非常流行,这里分享一下某个项目的大屏布局(忘了源码是哪个博主的了) 展示 这个界面整体是垂直布局,分为两个部分,标题是一个部分,然后下面的整体是一个layout布局,为另外一部分。 l…...
re:从0开始的CSS之旅 14. 显示模式的切换
1. 两个属性 display 属性可以用于转换元素的显示模式 可选值: block 转换为块元素 inline 转换为行内元素 inline-block 转换为行内块元素 none 不显示元素,并且不占用元素的位置 visibility 属性用于设置元素是否显示 可选值: visible 显示…...
K8S系列文章之 [Alpine基础环境配置]
用户手册:Alpine User Handbook 官方WIKI:Alpine Linux WIKI 安装 安装的实际逻辑是通过 setup-alpine 脚本去调用其他功能的脚本进行配置,可以通过 vi 查看脚本。如果某个部分安装失败,可退出后单独再次执行。通过镜像文件&a…...
单页404源码
<!doctype html> <html> <head> <meta charset"utf-8"> <title>简约 404错误页</title><link rel"shortcut icon" href"./favicon.png"><style> import url("https://fonts.googleapis.co…...
MySQL-运维
一、日志 1.错误日志 错误日志是MySQL中最重要的日志之一,它记录了当mysql启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关性息。当数据库出现任何故障导致无法正常使用时,建议首先查看此日志。 该日志是默认开启的…...
Waymo数据集下载与使用
在撰写论文时,接触到一个自动驾驶数据集Waymo Dataset 论文链接为:https://arxiv.org/abs/1912.04838v7 项目链接为:https://github.com/waymo-research/waymo-open-dataset 数据集链接为:https://waymo.com/open waymo提供了两种…...
蓝桥杯每日一题----素数筛
素数筛 素数筛的作用是筛选出[2,N]范围内的所有素数,本次主要讲解两种方法,分别是埃氏筛和欧拉筛。证明时会提到唯一分解定理,如果不知道的小伙伴可以先去学一学,那我们开始啦! 1.埃氏筛 主要思想:当找到…...
20240212请问如何将B站下载的软字幕转换成为SRT格式?
20240212请问如何将B站下载的软字幕转换成为SRT格式? 2024/2/12 12:47 百度搜索:字幕 json 转 srt json srt https://blog.csdn.net/a_wh_white/article/details/120687363?share_token2640663e-f468-4737-9b55-73c808f5dcf0 https://blog.csdn.net/a_w…...
《CSS 简易速速上手小册》第6章:高级 CSS 技巧(2024 最新版)
文章目录 6.1 使用 CSS 变量进行设计:魔法配方的调配6.1.1 基础知识6.1.2 重点案例:创建可定制的主题6.1.3 拓展案例 1:响应式字体大小6.1.4 拓展案例 2:使用 CSS 变量创建动态阴影效果 6.2 calc(), min(), max() 等函数的应用&am…...
2024-02-11 多进程、多线程 work
1. 创建一个多进程服务器和多线程服务器 a. 多进程 #include<myhead.h> #define PORT 9999 //端口号 #define IP "192.168.125.113" //IP地址//定义信号处理函数,用于回收僵尸进程 void handler(int signo) {if(signo S…...
详解结构体内存对齐及结构体如何实现位段~
目录 编辑 一:结构体内存对齐 1.1对齐规则 1.2.为什么存在内存对齐 1.3修改默认对齐数 二.结构体实现位段 2.1什么是位段 2.2位段的内存分配 2.3位段的跨平台问题 2.4位段的应用 2.5位段使用的注意事项 三.完结散花 悟已往之不谏,知来者犹可…...
Linux网络编程——tcp套接字
文章目录 主要代码关于构造listen监听accepttelnet测试读取信息掉线重连翻译服务器演示 本章Gitee仓库:tcp套接字 主要代码 客户端: #pragma once#include"Log.hpp"#include<iostream> #include<cstring>#include<sys/wait.h…...
【计算机网络】协议层次及其服务模型
协议栈(protocol stack) 物理层链路层网络层运输层应用层我们自顶向下,所以从应用层开始探究应用层 协议 HTTP 提供了WEB文档的请求和传送SMTP 提供电子邮件报文的传输FTP 提供两个端系统之间的文件传输报文(message)是…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
