146.LRU缓存

embedded/2024/11/14 22:02:55/

题目:

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

LCR 031. LRU 缓存 - 力扣(LeetCode)

题解:

思路:

用一个哈希表和一个双端队列,队列里面存储key,哈希存value。get时把对应的key删除,放在队首。put时有旧的则删掉,size够了把队列的最后一个删掉。然后加入,并且覆盖哈希表里面的值。

代码:

java">class LRUCache {private int capacity;private Map<Integer,Integer> cache;private Deque<Integer> queue;public LRUCache(int capacity) {this.capacity=capacity;this.cache=new HashMap<>();this.queue=new LinkedList<>();}public int get(int key) {if(cache.containsKey(key)){queue.remove(key);queue.offerFirst(key);return cache.get(key);}return -1;}public void put(int y, int value) {if(cache.containsKey(y)){queue.remove(y);}if(queue.size()==capacity){Integer oldKey=queue.pollLast();cache.remove(oldKey);}cache.put(y,value);queue.offerFirst(y);}
}

java">class Node {int data;Node next;Node prev;Node(int data) {this.data = data;}
}class MyDeque {private Node front;private Node rear;private int size;public MyDeque() {front = null;rear = null;size = 0;}// 向队列前端添加元素public void offerFirst(int data) {Node newNode = new Node(data);if (isEmpty()) {front = newNode;rear = newNode;} else {newNode.next = front;front.prev = newNode;front = newNode;}size++;}// 移除指定元素public void remove(int key) {Node current = front;while (current != null) {if (current.data == key) {if (current == front) {pollFirst();} else if (current == rear) {pollLast();} else {current.prev.next = current.next;current.next.prev = current.prev;size--;}return;}current = current.next;}return;}// 从队列尾部移除元素public int pollLast() {if (isEmpty()) {return -1;}int removedData = rear.data;if (size == 1) {front = null;rear = null;} else {rear = rear.prev;rear.next = null;}size--;return removedData;}// 从队列前端移除元素public int pollFirst() {if (isEmpty()) {return -1;}int removedData = front.data;if (size == 1) {front = null;rear = null;} else {front = front.next;front.prev = null;}size--;return removedData;}// 判断队列是否为空public boolean isEmpty() {return size == 0;}// 获取队列大小public int size() {return size;}}

完整的双端队列:

java">class Node {int data;Node next;Node prev;Node(int data) {this.data = data;}
}public class MyDeque {private Node front;private Node rear;private int size;public MyDeque() {front = null;rear = null;size = 0;}// 向队列前端添加元素public void addFirst(int data) {Node newNode = new Node(data);if (isEmpty()) {front = newNode;rear = newNode;} else {newNode.next = front;front.prev = newNode;front = newNode;}size++;}// 向队列尾部添加元素public void addLast(int data) {Node newNode = new Node(data);if (isEmpty()) {front = newNode;rear = newNode;} else {rear.next = newNode;newNode.prev = rear;rear = newNode;}size++;}// 从队列前端移除元素public int removeFirst() {if (isEmpty()) {throw new IllegalStateException("队列为空");}int removedData = front.data;if (size == 1) {front = null;rear = null;} else {front = front.next;front.prev = null;}size--;return removedData;}// 从队列尾部移除元素public int removeLast() {if (isEmpty()) {throw new IllegalStateException("队列为空");}int removedData = rear.data;if (size == 1) {front = null;rear = null;} else {rear = rear.prev;rear.next = null;}size--;return removedData;}// 移除指定元素public void remove(int key) {Node current = front;while (current != null) {if (current.data == key) {if (current == front) {removeFirst();} else if (current == rear) {removeLast();} else {current.prev.next = current.next;current.next.prev = current.prev;size--;}return;}current = current.next;}throw new IllegalArgumentException("队列中没有该元素");}// 获取队列前端元素public int getFirst() {if (isEmpty()) {throw new IllegalStateException("队列为空");}return front.data;}// 获取队列尾部元素public int getLast() {if (isEmpty()) {throw new IllegalStateException("队列为空");}return rear.data;}// 判断队列是否为空public boolean isEmpty() {return size == 0;}// 获取队列大小public int size() {return size;}}


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

相关文章

基于函数计算FC3.0 部署AI数字绘画stable-diffusion自定义模型

基于函数计算FC3.0 部署AI数字绘画stable-diffusion自定义模型 部署AI数字绘画stable-diffusion曲线救国授权github账号 部署ffmpeg-app-v3总结 在讲述了函数计算FC3.0和函数计算FC2.0的操作界面UI改版以及在函数管理、函数执行引擎、自定义域名、函数授权及弹性伸缩规则方面进…

JS-37-jQuery06-ajax

用JavaScript写AJAX前面已经介绍过了&#xff0c;主要问题就是不同浏览器需要写不同代码&#xff0c;并且状态和错误处理写起来很麻烦。 用JavaScript写AJAX 用jQuery的相关对象来处理AJAX&#xff0c;不但不需要考虑浏览器问题&#xff0c;代码也能大大简化。 一、ajax()函数…

vscode vue template模板中 tab键无法快速补全

之前记得一直可以的突然不知道咋的就不行了… 解决办法: 菜单栏 - 文件 - 首选项 - 设置- emmet:tab ✔就好了

一个文生视频MoneyPrinterTurbo项目解析

最近抖音剪映发布了图文生成视频功能&#xff0c;同时百家号也有这个功能&#xff0c;这个可以看做是一个开源的实现&#xff0c;一起看看它的原理吧~ 一句话提示词 大模型生成文案 百家号生成视频效果 MoneyPrinterTurbo生成视频效果 天空为什么是蓝色的&#xff1f; 天空…

GPT-Engineer:一个基于OpenAI的GPT-4模型的开源项目,旨在自动化软件工程任务,如代码生成、需求澄清和规范生成

GPT-Engineer是一个基于OpenAI的GPT-4模型的开源项目,旨在自动化软件工程任务,如代码生成、需求澄清和规范生成等38。它通过与GPT-4模型以对话方式交互,根据提供的提示或指令自动生成代码库或完成特定的软件开发任务256。这个工具特别适合于快速原型设计和开发复杂应用程序,…

web server apache tomcat11-10-Class Loader

前言 整理这个官方翻译的系列&#xff0c;原因是网上大部分的 tomcat 版本比较旧&#xff0c;此版本为 v11 最新的版本。 开源项目 从零手写实现 tomcat minicat 别称【嗅虎】心有猛虎&#xff0c;轻嗅蔷薇。 系列文章 web server apache tomcat11-01-官方文档入门介绍 web…

【再探】设计模式-设计原则

设计原则是在编写程序时引导程序员遵循的一些原则和准则。这些原则旨在提高代码的可读性、可维护性、可扩展性和可重用性。 可读性&#xff1a;理解和沟通的难易程度。可维护性&#xff1a;修改和调整的难易程度。可扩展性&#xff1a;应对未来变化的能力。可重用性&#xff1…

Oracle EBS Interface/API(54)- GL日记账审批

背景: 客户化创建薪酬凭证或者银企付款入账日记账以后,用户希望自动提交审批流程,无需到系统标准功能点击审批,减少用户操作。 快速参考 参考点内容功能导航N: GL->日记账->输入并发请求None基表GL.GL_JE_BATCHESAPI参考下面介绍错误信息表None接口FormNone接口Reque…