LFU算法
LFU算法
Least Frequently Used(最不频繁使用)

Leetcode有原题,之前手写过LRU,数据结构还是习惯于用java实现,实现是copy的评论题解。
题解注释写的很清楚
大致就是说LFUCache类维护一个存放node的map,同时维护两个双向链表,注意这个双向链表里面又包含了两个双向链表,访问的频率是first最大,last最小。其余的就是正常的双向链表的操作了(插入,删除)
import java.util.HashMap;
import java.util.Map;class LFUCache {Map<Integer, Node> cache; // 存储缓存的内容,Node中除了value值外,还有key、freq、所在doublyLinkedList、所在doublyLinkedList中的postNode、所在doublyLinkedList中的preNode,具体定义在下方。DoublyLinkedList firstLinkedList; // firstLinkedList.post 是频次最大的双向链表DoublyLinkedList lastLinkedList; // lastLinkedList.pre 是频次最小的双向链表,满了之后删除 lastLinkedList.pre.tail.pre// 这个Node即为频次最小且访问最早的Nodeint size;int capacity;public LFUCache(int capacity) {cache = new HashMap<>(capacity);firstLinkedList = new DoublyLinkedList();lastLinkedList = new DoublyLinkedList();firstLinkedList.post = lastLinkedList; // 是按照倒序排列的,最大的是firstlastLinkedList.pre = firstLinkedList;this.capacity = capacity;}public int get(int key) {Node node = cache.get(key);if (node == null) {return -1;}// 该key访问频次+1freqInc(node);return node.value;}public void put(int key, int value) {if (capacity == 0) {return;}Node node = cache.get(key);// 若key存在,则更新value,访问频次+1if (node != null) {node.value = value;freqInc(node);} else {// 若key不存在if (size == capacity) {// 如果缓存满了,删除lastLinkedList.pre这个链表(即表示最小频次的链表)中的tail.pre这个Node(即最小频次链表中最先访问的Node),如果该链表中的元素删空了,则删掉该链表。cache.remove(lastLinkedList.pre.tail.pre.key);lastLinkedList.removeNode(lastLinkedList.pre.tail.pre);size--;if (lastLinkedList.pre.head.post == lastLinkedList.pre.tail) {removeDoublyLinkedList(lastLinkedList.pre);}}// cache中put新Key-Node对儿,并将新node加入表示freq为1的DoublyLinkedList中,若不存在freq为1的DoublyLinkedList则新建。Node newNode = new Node(key, value);cache.put(key, newNode);if (lastLinkedList.pre.freq != 1) {DoublyLinkedList newDoublyLinedList = new DoublyLinkedList(1);addDoublyLinkedList(newDoublyLinedList, lastLinkedList.pre);newDoublyLinedList.addNode(newNode);} else {lastLinkedList.pre.addNode(newNode);}size++;}}/*** node的访问频次 + 1*/void freqInc(Node node) {// 将node从原freq对应的双向链表里移除, 如果链表空了则删除链表。DoublyLinkedList linkedList = node.doublyLinkedList;DoublyLinkedList preLinkedList = linkedList.pre;linkedList.removeNode(node);if (linkedList.head.post == linkedList.tail) {removeDoublyLinkedList(linkedList);}// 将node加入新freq对应的双向链表,若该链表不存在,则先创建该链表。node.freq++;if (preLinkedList.freq != node.freq) {DoublyLinkedList newDoublyLinedList = new DoublyLinkedList(node.freq);addDoublyLinkedList(newDoublyLinedList, preLinkedList);newDoublyLinedList.addNode(node);} else {preLinkedList.addNode(node);}}/*** 增加代表某1频次的双向链表*/void addDoublyLinkedList(DoublyLinkedList newDoublyLinedList, DoublyLinkedList preLinkedList) {newDoublyLinedList.post = preLinkedList.post;newDoublyLinedList.post.pre = newDoublyLinedList;newDoublyLinedList.pre = preLinkedList;preLinkedList.post = newDoublyLinedList;}/*** 删除代表某1频次的双向链表*/void removeDoublyLinkedList(DoublyLinkedList doublyLinkedList) {doublyLinkedList.pre.post = doublyLinkedList.post;doublyLinkedList.post.pre = doublyLinkedList.pre;}}class Node {int key;int value;int freq = 1;Node pre; // Node所在频次的双向链表的前继NodeNode post; // Node所在频次的双向链表的后继NodeDoublyLinkedList doublyLinkedList; // Node所在频次的双向链表public Node() {}public Node(int key, int value) {this.key = key;this.value = value;}}class DoublyLinkedList {int freq; // 该双向链表表示的频次DoublyLinkedList pre; // 该双向链表的前继链表(pre.freq < this.freq)DoublyLinkedList post; // 该双向链表的后继链表 (post.freq > this.freq)Node head; // 该双向链表的头节点,新节点从头部加入,表示最近访问Node tail; // 该双向链表的尾节点,删除节点从尾部删除,表示最久访问public DoublyLinkedList() {head = new Node();tail = new Node();head.post = tail;tail.pre = head;}public DoublyLinkedList(int freq) {head = new Node();tail = new Node();head.post = tail;tail.pre = head;this.freq = freq;}void removeNode(Node node) {node.pre.post = node.post;node.post.pre = node.pre;}void addNode(Node node) {node.post = head.post;head.post.pre = node;head.post = node;node.pre = head;node.doublyLinkedList = this;}}相关文章:
LFU算法
LFU算法 Least Frequently Used(最不频繁使用) Leetcode有原题,之前手写过LRU,数据结构还是习惯于用java实现,实现是copy的评论题解。 题解注释写的很清楚 大致就是说LFUCache类维护一个存放node的map,同…...
JVM系列-7内存调优
👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术、JVM原理🔥如果感觉博主的文…...
[UI5 常用控件] 01.Text
文章目录 前言1. 普通文本2. 长文本:3. 设置最大显示行数 ( maxLines3 )4. 单行显示 ( wrappingfalse )5. 显示空白符 ( renderWhitespacetrue )6. 使用 - 连接单词:只适用于英文 ( wrappingTypeHyphenated )7. 空白时使用 - 代替 ( emptyIndicatorModeOn )8. JSON数…...
C语言之指针的地址和指向的内容总结(八十四)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...
1月25日,每日信息差
第一、中国和新加坡互免签证,新加坡酒店搜索量较发布前增长4倍。去哪儿数据显示,新加坡酒店搜索量较发布前增长4倍,仍在持续增长中。同程旅行数据显示,消息发布半小时内,同程旅行平台新加坡相关搜索热度较前日同一时段…...
前端工程化之:webpack1-3(模块化兼容性)
一、模块化兼容性 由于 webpack 同时支持 CommonJs 和 ES6 module ,因此需要理解它们互操作时 webpack 是如何处理的。 二、同模块化标准 如果导出和导入使用的是同一种模块化标准,打包后的效果和之前所说的模块化没有任何差异。 CommonJSÿ…...
JDK8新特性(一)
一、概述 JDK8,又称为JDK 1.8,是Java语言开发的里程碑版本。这个版本引入了众多令人兴奋的新特性,让Java更加灵活和强大。其中,最引人注目的新特性包括Lambda表达式、方法引用、默认方法、Stream API、新的日期和时间API以及Optio…...
java实现ftp协议远程网络下载文件
引言 在开发过程中,偶尔会遇到网络文件在FTP服务上存储着,对于这种情况想要下载到本地还有些麻烦,我们直接上世界上最简单的代码。 How to do 1.提前引入包 <!--hutool万能工具包--><dependency><groupId>cn.hutool<…...
深入浅出理解目标检测的NMS非极大抑制
一、参考资料 物体检测中常用的几个概念迁移学习、IOU、NMS理解 目标定位和检测系列(3):交并比(IOU)和非极大值抑制(NMS)的python实现 Pytorch:目标检测网络-非极大值抑制(NMS) …...
HbuilderX报错“Error: Fail to open IDE“,以及运行之后没有打开微信开发者,或者运行没有反应的解决办法
开始 问题:HbuilderX启动时,打开微信开发者工具报错"Error: Fail to open IDE",以及运行之后没有打开微信开发者,或者运行没有反应的解决办法! 解决办法: 按照步骤一步一步完成分析,除非代码报错,否则都是可以启动的 第一步:检查HbuildX是否登录账号 第二步:检查微信…...
【Go 快速入门】基础语法 | 流程控制 | 字符串
文章目录 基础语法值变量常量运算符指针new 和 make 区别 字符串byte 和 rune 类型 流程控制for 循环If else 分支switch 分支 基础语法 项目代码地址:02-basicgrammar 值 基本类型值 Go 最基础的数据类型,比如整型、浮点型、布尔型。 复合类型值 …...
腾讯云轻量应用Ubuntu服务器如何一键部署幻兽帕鲁Palworld私服?
幻兽帕鲁/Palworld是一款2024年Pocketpair开发的开放世界生存制作游戏,在帕鲁的世界,玩家可以选择与神奇的生物“帕鲁”一同享受悠闲的生活,也可以投身于与偷猎者进行生死搏斗的冒险。而帕鲁可以进行战斗、繁殖、协助玩家做农活,也…...
Redis的SDS你了解吗?
初识SDS: Redis的String和其他很多编程语言中的语义相似,它能够表达3种值的类型: 1.字符串 2.整数 3.浮点数 三种类型根据具体场景由Redis完成相互之间的自动转换,并且根据需要选取底层的承载方式,Redis内部&#x…...
C#中常见的软件设计模式及应用场景
文章目录 前言1、单例模式 (Singleton)1.1 详细说明1.2 应用场景示例 2、工厂模式 (Factory Method)2.1 详细说明2.2 应用场景示例 3、观察者模式 (Observer)3.1 详细说明3.2 应用场景示例 4、策略模式 (Strategy)4.1 详细说明4.2 应用场景示例 5、适配器模式 (Adapter)5.1 详细…...
字符串相关函数和文件操作
文章目录 1. C/C 字符串概述1.1 字符串常量1.2 字符数组 2. 字符串函数2.1 拷贝赋值功能相关函数(覆盖)2.1.1 strcpy2.1.2 strncpy2.1.3 memcpy2.1.4 memmove2.1.5 memset2.1.6 注意小点2.1.7 【函数区别】 2.2 追加功能相关函数2.2.1 strcat2.2.2 strnc…...
【c++学习】数据结构中的栈
c栈 栈代码用线性表实现栈用链表实现栈 栈 栈:先进后出 只对栈顶元素进行操作,包括新元素入栈、栈顶元素出栈和查看栈顶元素(只支持对栈顶的增、删、查)。 代码 下述代码实现了栈及其接口 包括对栈顶的增、删、查以及查看栈的大…...
新建react项目,react-router-dom配置路由,引入antd
提示:reactrouter6.4版本,与reactrouter5.0的版本用法有区别,互不兼容需注意 文章目录 前言一、创建项目二、新建文件并引入react-router-dom、antd三、配置路由跳转四、效果五、遇到的问题六、参考文档总结 前言 需求:新建react项…...
Transformer and Pretrain Language Models3-6
Pretrain Language Models预训练语言模型 content: language modeling(语言模型知识) pre-trained langue models(PLMs)(预训练的模型整体的一个分类) fine-tuning approaches GPT and BERT(…...
Linux系统中编写bash脚本进行mysql的数据同步
一、为何要用脚本做数据同步 (一)、问题 我们的视频监控平台云服务器,需要向上级的服务器定期同步一些数据表的数据,前期做了个程序,可以实现同步。但是,现在数据库的结构改了,结果又需要该程序…...
光耦驱动继电器电路图大全
光耦驱动继电器电路图(一) 注: 1U1-1脚可接12V,也可接5V,1U1导通,1Q1导通,1Q1-30V,线圈两端电压为11.7V. 1U1-1脚不接或接地,1U1不通,1Q1截止,1…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
门静脉高压——表现
一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...
