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

460. LFU 缓存

请你为 最不经常使用(LFU)缓存算法设计并实现数据结构。

实现 LFUCache 类:

  • LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象
  • int get(int key) - 如果键 key 存在于缓存中,则获取键的值,否则返回 -1 。
  • void put(int key, int value) - 如果键 key 已存在,则变更其值;如果键不存在,请插入键值对。当缓存达到其容量 capacity 时,则应该在插入新项之前,移除最不经常使用的项。在此问题中,当存在平局(即两个或更多个键具有相同使用频率)时,应该去除 最久未使用 的键。

为了确定最不常使用的键,可以为缓存中的每个键维护一个 使用计数器 。使用计数最小的键是最久未使用的键。

当一个键首次插入到缓存中时,它的使用计数器被设置为 1 (由于 put 操作)。对缓存中的键执行 get 或 put 操作,使用计数器的值将会递增。

函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

示例:

输入:
["LFUCache", "put", "put", "get", "put", "get", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [3], [4, 4], [1], [3], [4]]
输出:
[null, null, null, 1, null, -1, 3, null, -1, 3, 4]解释:
// cnt(x) = 键 x 的使用计数
// cache=[] 将显示最后一次使用的顺序(最左边的元素是最近的)
LFUCache lfu = new LFUCache(2);
lfu.put(1, 1);   // cache=[1,_], cnt(1)=1
lfu.put(2, 2);   // cache=[2,1], cnt(2)=1, cnt(1)=1
lfu.get(1);      // 返回 1// cache=[1,2], cnt(2)=1, cnt(1)=2
lfu.put(3, 3);   // 去除键 2 ,因为 cnt(2)=1 ,使用计数最小// cache=[3,1], cnt(3)=1, cnt(1)=2
lfu.get(2);      // 返回 -1(未找到)
lfu.get(3);      // 返回 3// cache=[3,1], cnt(3)=2, cnt(1)=2
lfu.put(4, 4);   // 去除键 1 ,1 和 3 的 cnt 相同,但 1 最久未使用// cache=[4,3], cnt(4)=1, cnt(3)=2
lfu.get(1);      // 返回 -1(未找到)
lfu.get(3);      // 返回 3// cache=[3,4], cnt(4)=1, cnt(3)=3
lfu.get(4);      // 返回 4// cache=[3,4], cnt(4)=2, cnt(3)=3

提示:

  • 1 <= capacity <= 104
  • 0 <= key <= 105
  • 0 <= value <= 109
  • 最多调用 2 * 105 次 get 和 put 方法


其中 cnt 表示缓存使用的频率,time 表示缓存的使用时间,key 和 value 表示缓存的键值。

题解:比较直观的想法就是我们用哈希表 key_table 以键 key 为索引存储缓存,建立一个平衡二叉树 S 来保持缓存根据 (cnt,time) 双关键字。还有一道类似的题LRU:146. LRU 缓存机制-CSDN博客

code:

class LFUCache {// 缓存容量,时间戳int capacity, time;Map<Integer, Node> key_table;TreeSet<Node> S;public LFUCache(int capacity) {this.capacity = capacity;this.time = 0;key_table = new HashMap<Integer, Node>();S = new TreeSet<Node>();}public int get(int key) {if (capacity == 0) {return -1;}// 如果哈希表中没有键 key,返回 -1if (!key_table.containsKey(key)) {return -1;}// 从哈希表中得到旧的缓存Node cache = key_table.get(key);// 从平衡二叉树中删除旧的缓存S.remove(cache);// 将旧缓存更新cache.cnt += 1;cache.time = ++time;// 将新缓存重新放入哈希表和平衡二叉树中S.add(cache);key_table.put(key, cache);return cache.value;}public void put(int key, int value) {if (capacity == 0) {return;}if (!key_table.containsKey(key)) {// 如果到达缓存容量上限if (key_table.size() == capacity) {// 从哈希表和平衡二叉树中删除最近最少使用的缓存key_table.remove(S.first().key);S.remove(S.first());}// 创建新的缓存Node cache = new Node(1, ++time, key, value);// 将新缓存放入哈希表和平衡二叉树中key_table.put(key, cache);S.add(cache);} else {// 这里和 get() 函数类似Node cache = key_table.get(key);S.remove(cache);cache.cnt += 1;cache.time = ++time;cache.value = value;S.add(cache);key_table.put(key, cache);}}
}class Node implements Comparable<Node> {int cnt, time, key, value;Node(int cnt, int time, int key, int value) {this.cnt = cnt;this.time = time;this.key = key;this.value = value;}public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof Node) {Node rhs = (Node) anObject;return this.cnt == rhs.cnt && this.time == rhs.time;}return false;}public int compareTo(Node rhs) {return cnt == rhs.cnt ? time - rhs.time : cnt - rhs.cnt;}public int hashCode() {return cnt * 1000000007 + time;}
}

相关文章:

460. LFU 缓存

请你为 最不经常使用&#xff08;LFU&#xff09;缓存算法设计并实现数据结构。 实现 LFUCache 类&#xff1a; LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象int get(int key) - 如果键 key 存在于缓存中&#xff0c;则获取键的值&#xff0c;否则返回 -1…...

YOLOV8 C++ opecv_dnn模块部署

废话不多说:opencv>4.7.0 opencv编译不做解释&#xff0c;需要的话翻看别的博主的编译教程 代码饱含V5,V7,V8部署内容 头文件yoloV8.h #pragma once #include<iostream> #include<opencv2/opencv.hpp> using namespace std; using namespace cv; using name…...

STM32 DMA从存储器发送数据到串口

1.任务描述 &#xff08;1&#xff09;ds18b20测量环境温度存储到存储器&#xff08;数组&#xff09;中。 &#xff08;2&#xff09;开启DMA将数组中的内容&#xff0c;通过DMA发送到串口 存在问题&#xff0c;ds18b20读到的数据是正常的&#xff0c;但是串口只是发送其低…...

Flask连接数据库返回json数据

常用方法: json.dumps(字典) 将python的字典转换为json字符串json.loads(字符串) 将字符串转换为python中的字典方法一:将python字典转化为json from flask import Flask import jsonapp Flask(__name__)app.route("/index") def index():# 返回json数据的方法…...

Openresty通过Lua+Redis 实现动态封禁IP

求背景 为了封禁某些爬虫或者恶意用户对服务器的请求&#xff0c;我们需要建立一个动态的 IP 黑名单。对于黑名单之内的 IP &#xff0c;拒绝提供服务。并且可以设置失效 1.安装Openresty&#xff08;编译安装&#xff09; wget https://openresty.org/download/openresty-1.…...

碎片笔记|AIGC核心技术综述

前言&#xff1a;AIGC全称为AI-Generated Content&#xff0c;直译为人工智能内容生成。即采用人工智能技术来自动生产内容。AIGC在2022年的爆发&#xff0c;主要是得益于深度学习模型方面的技术创新。不断涌现的生成算法、预训练模型以及多模态等技术的融合引发了AIGC的技术变…...

28385-2012 印刷机械 锁线机 学习笔记

声明 本文是学习GB-T 28385-2012 印刷机械 锁线机. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了锁线机的型式、基本参数、要求、试验方法、检验规则、标志、包装、运输与贮存。 本标准适用于用线将书帖装订成书芯的锁线机。 …...

【大规模 MIMO 检测】基于ADMM的大型MU-MIMO无穷大范数检测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

MySQL数据库记录的删除操作与特殊字符

在数据库管理中,除了添加和修改记录之外,删除操作也是一个重要的方面。同时特殊字符序列的处理也是必不可少的一步。 本文将深入探讨如何在MySQL数据库中进行表记录的删除操作,以及如何处理特殊字符序列。将使用《三国志》游戏数据作为示例来进行解释。 文章目录 表记录的…...

什么是TypeScript

TypeScript是一个开源的编程语言&#xff0c;它是JavaScript的超集。它允许开发人员编写更具可靠性和高效性的代码&#xff0c;同时提供了强类型支持、类、接口、模块等新的特性。TypeScript的代码可以编译成纯JavaScript代码&#xff0c;可以在任何支持JavaScript的平台上运行…...

[docker]笔记-网络故障处理

1、同事在虚拟机上部署docker&#xff0c;发现电脑无法登录虚拟机了。首先ping测是通的&#xff0c;从我电脑继续进行登录测试发现没问题&#xff0c;初步判断是她电脑网络和虚拟机网络之间连接出错。 2、进行虚拟机登录查看&#xff0c;首先使用route -n命令查看路由&#xf…...

牛客网_HJ1_字符串最后一个单词的长度

HJ1_字符串最后一个单词的长度 原题思路代码运行截图收获 原题 字符串最后一个单词的长度 思路 从最后一个字符开始遍历&#xff0c;遇到第一个空格时的长度即为最后一个单词的长度 代码 #include <iostream> #include <string> using namespace std;int main…...

智算创新,美格智能助力智慧支付加速发展

9月21日&#xff0c;以“智算引领创新未来”为主题的紫光展锐2023泛物联网终端生态论坛在深圳举行。作为紫光展锐重要战略合作伙伴&#xff0c;美格智能标准模组产品线总经理郭强华、高级产品总监刘伟鹏受邀出席论坛。美格智能基于紫光展锐5G、4G、智能SoC、Cat.1 bis等芯片平台…...

常用SQL语法总结

1.库操作 1.1.创建数据库 CREATE DATABASE 语句用来创建一个新的数据库。 语法&#xff1a;CREATE DATABASE DatabaseName; DatabaseName 为数据库名字&#xff0c;它的名字必须是唯一的&#xff0c;不能和其它数据库重名。 1.2.删除数据库 DROP DATABASE语句用来删除已经…...

Promise击鼓传花的游戏

Promise击鼓传花的游戏 Promise系列导航前言一、学习Promise的原因二、揭开击鼓传花游戏的面纱补充小知识 Promise系列导航 1.Promise本质击鼓传花的游戏 2.Promise四式击鼓 3.Promise击鼓传花 4.Promise花落谁家知多少 前言 &#x1f468;‍&#x1f4bb;&#x1f468;‍&…...

蓝桥杯每日一题2023.9.29

蓝桥杯大赛历届真题 - C&C 大学 B 组 - 蓝桥云课 (lanqiao.cn) 题目描述1 题目分析 看见有32位&#xff0c;我们以此为入手点&#xff0c; B代表字节1B 8b b代表位&#xff0c;32位即4个字节 (B) 1KB 1024B 1MB 1024KB (256 * 1024 * 1024) / 4 67108864 故答案…...

Spring Boot的自动装配中的@ConditionalOnBean条件装配注解在Spring启动过程中,是如何保证处理顺序靠后的

前言 为什么Spring Boot条件注解那么多&#xff0c;而标题中是ConditionalOnBean呢&#xff1f; 因为&#xff0c;相比之下我们用的比较多的条件装配注解也就是ConditionalOnClass、ConditionalOnBean了&#xff0c;而ConditionalOnClass对顺序并不敏感&#xff08;说白了就是判…...

玩转数据-大数据-Flink SQL 中的时间属性

一、说明 时间属性是大数据中的一个重要方面&#xff0c;像窗口&#xff08;在 Table API 和 SQL &#xff09;这种基于时间的操作&#xff0c;需要有时间信息。我们可以通过时间属性来更加灵活高效地处理数据&#xff0c;下面我们通过处理时间和事件时间来探讨一下Flink SQL …...

【论文笔记】A Review of Motion Planning for Highway Autonomous Driving

文章目录 I. INTRODUCTIONII. CONSIDERATIONS FOR HIGHWAY MOTION PLANNINGA. TerminologyB. Motion Planning SchemeC. Specificities of Highway DrivingD. Constraints on Highway DrivingE. What Is at Stake in this Paper III. STATE OF THE ARTA. Taxonomy DescriptionB…...

YOLOv8改进算法之添加CA注意力机制

1. CA注意力机制 CA&#xff08;Coordinate Attention&#xff09;注意力机制是一种用于加强深度学习模型对输入数据的空间结构理解的注意力机制。CA 注意力机制的核心思想是引入坐标信息&#xff0c;以便模型可以更好地理解不同位置之间的关系。如下图&#xff1a; 1. 输入特…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...