LRU缓存算法,大厂面试会手撕

embedded/2024/11/14 3:08:54/

计算机的缓存容量有限,如果缓存满了就要删除⼀些内容,给新内容腾位置。但问题是,删除哪些内容呢?
我们肯定希望删掉哪些没什么⽤的缓存,⽽把有⽤的数据继续留在缓存⾥,⽅便之后继续使⽤。那么,什么样的数据,我们判定为「有⽤的」的数据呢?
LRU 缓存淘汰算法就是⼀种常⽤策略。LRU 的全称是 Least Recently Used,也就是说我们认为最近使⽤过的 数据应该是是「有⽤的」,很久都没⽤过的数据应该是⽆⽤的,内存满了就优先删那些很久没⽤过的数据。

代码


public class Node {public int key, value;public Node pre, next; //双链表 前一个和后一个public Node(int key, int value) {this.value = value;this.key = key;}}
public class DoubleList {public Node head, tail;public int size;//构造出来下面的链表public DoubleList() {head = new Node(0, 0);tail = new Node(0, 0);head.next = tail;tail.pre = head;size = 0;}//双链表尾部插入public void addLast(Node x) {//在末尾添x.pre = tail.pre;x.next = tail;tail.pre.next = x;tail.pre = x;size++;}// remove (x)public void remove(Node x) {x.pre.next = x.next;x.next.pre = x.pre;size--;}//删除 removeFirst  size(public Node removeFirst() {if (head.next == null) {return null;}Node first = head.next;remove(first);return first;}public int size() {return size;}@Overridepublic String toString() {return "DoubleList{" +"head=" + head +", tail=" + tail +", size=" + size +'}';}
}import java.util.HashMap;public class LRUCache {private HashMap<Integer, Node> map;private DoubleList cache;private int cap;public LRUCache(int capacity) {this.cap = capacity;map = new HashMap<>();cache = new DoubleList();}public int get(int key) {//查找一个值//如果不含有 直接返回if (!map.containsKey(key)) {return -1;}//将这个值变为最近使用的makeRecently(key);//返回map里面的值return map.get(key).value;}public void put(int key, int value) {//key已经存在   修改为最近使用if (map.containsKey(key)) {deleteKey(key);addRecently(key, value);return;}if (cap == cache.size) {removeLeastRecently();}//不存在  添加keyaddRecently(key, value);//容量慢了 淘汰头节点 也就是最久没有使用的key//容量没有慢  插入key和val为最近使用的数据}//删除最久的元素public void removeLeastRecently() {Node deleteNode = cache.removeFirst();map.remove(deleteNode.key);}public void makeRecently(int key) {Node x = map.get(key);//先删除cache.remove(x);//添加cache.addLast(x);}public void addRecently(int key, int value) {Node x = new Node(key, value);cache.addLast(x);map.put(key, x);}/*** 两个地方都要删** @param key*/public void deleteKey(int key) {Node x = map.get(key);cache.remove(x);map.remove(key);}@Overridepublic String toString() {return "LRUCache{" +"map=" + map +", cache=" + cache +", cap=" + cap +'}';}
}

http://www.ppmy.cn/embedded/102291.html

相关文章

结合令牌(JWT)和签名认证的系统登录及页面访问的详细实现原理和流程

结合令牌&#xff08;JWT&#xff09;和签名认证的系统登录及页面访问的详细实现原理和流程如下&#xff1a; 1. 实现原理 1.1 JWT&#xff08;JSON Web Token&#xff09;令牌 JWT是一种用于用户认证的紧凑、安全的令牌格式。它通常由三部分组成&#xff1a; Header&#…

免费JSON在线解析工具网址

1&#xff0c;https://tool.juhe.cn/ JSON在线解析 (juhe.cn) 2&#xff0c;https://www.sojson.com/ JSON在线 | JSON解析格式化—SO JSON在线工具

java整合Redis

Jedis Jedis是Redis官方推荐的Java连接开发工具&#xff0c;是一个用于连接和操作Redis数据库的Java客户端库。它提供了一系列的方法来操作Redis的键值存储、列表、哈希、集合和有序集合等数据结构。要在Java开发中使用好Redis中间件&#xff0c;必须对Jedis熟悉才能写成漂亮的…

英特尔终止开发开源 H.265/HEVC 编码器项目

作为英特尔可扩展视频技术&#xff08;SVT&#xff09;计划的一部分&#xff0c;一直以来他们持续在开发 SVT-HEVC&#xff0c;这是一款 BSD 许可的高性能 H.265/HEVC 视频编码器&#xff0c;针对至强可扩展处理器和至强 D 处理器进行了优化。但最近他们改变了方向&#xff0c;…

2024生成式AI商业落地白皮书_火山引擎

更多详细内容请下载资源 2024生成式AI商业落地白皮书-火山引擎

使用Dockerfile创建应用镜像

在Docker file中定义所需要执⾏的指令&#xff0c;使⽤ docker build创建镜 像&#xff0c;过程中会按照dockerfile所定义的内容进⾏打开临时性容器&#xff0c;把 docker file中命令全部执⾏完成&#xff0c;就得到了⼀个容器应⽤镜像&#xff0c;每 ⼀⾏命令都会出现容器&…

【C++对于C语言的扩充】:auto关键字、范围for以及nullptr

文章目录 &#x1f680;auto关键字&#xff08;C11&#xff09;✈️auto介绍✈️auto的使用细则✈️auto不能使用的场景 &#x1f680;范围for&#xff08;C11&#xff09;✈️范围for介绍✈️范围for的使用条件 &#x1f680;指针空值nullptr&#xff08;C11&#xff09; &…

Spring Boot 应用中注册和使用 Filter

文章目录 1. 使用 WebFilter 注解2. 实现 Filter 接口并注册为 Spring Bean3. 使用 Spring Security 提供的 Filter4. 使用 Spring Boot Actuator 的 EndpointFilter注意事项 在Spring Boot中&#xff0c;Filter&#xff08;过滤器&#xff09;是一个用于在Servlet请求到达目标…