力扣146. LRU 缓存

Problem: 146. LRU 缓存

文章目录

  • 题目描述
  • 思路
  • 复杂度
  • Code

题目描述

在这里插入图片描述在这里插入图片描述

思路

主要说明大致思路,具体实现看代码。

1.为了实现题目中的O(1)时间复杂度的get与put方法,我们利用哈希表和双链表的结合,将key作为键,对应的链表的节点作为值(也就是在此处我们用一个节点类作为值);
2.定义双链表的节点类,其中包含每次put的键与对应的值,还包括前驱、后驱指针;
3.编写双链表的实现类,并实现:

3.1.初始化一个双链表(创建虚拟头、尾节点;由于我们要实现将最就不使用的节点删除,我们在此使用尾插法即每次链表尾部位最近使用的,表头为最久不适用的);
3.2.实现尾插一个节点;
3.3.实现删除一个给定的节点;
3.4.实现从表头删除一个节点(删除最久不使用的节点)
3.5.返回链表的长度

4.实现LRUCache类:

4.1. 创建哈希表map与双链表cache;
4.2. 为了不直接在get与put中对map与cache操作带来麻烦(主要操作是同步在mao中添加key同时在cache中增、删、改对应节点的值),我们封装实现一些API(具体操作实现看代码)
4.3. 实现get与put方法(直接看代码)

复杂度

时间复杂度:

O ( n ) O(n) O(n);其中 n n n为要操作的次数

空间复杂度:

O ( n ) O(n) O(n)

Code

/*** Node class*/
class Node {public int key;public int val;public Node next;public Node prev;public Node(int k, int v) {this.key = k;this.val = v;}
}class DoubleList {//The dummy node of head and tail to a double linked listprivate Node head;private Node tail;//The size of a linked listprivate int size;public DoubleList() {//Initialize the element of double linked listhead = new Node(0, 0);tail = new Node(0, 0);head.next = tail;tail.prev = head;size = 0;}// Add node x at the end of the list, time O(1)// Tail insertion method of bidirectional linked list// with virtual head and tail nodespublic void addLast(Node x) {x.prev = tail.prev;x.next = tail;tail.prev.next = x;tail.prev = x;size++;}// Delete the x node in the linked list (x must exist)// Since it is a double-linked list and given to the target Node,// time O(1)public void remove(Node x) {x.prev.next = x.next;x.next.prev = x.prev;size--;}// Delete the first node in the linked list// and return the node, time O(1)public Node removeFirst() {if (head.next == null) {return null;}Node first = head.next;remove(first);return first;}// Return list length, time O(1)public int size() {return size;}
}class LRUCache {private HashMap<Integer, Node> map;private DoubleList cache;//Max capacityprivate int cap;public LRUCache(int capacity) {this.cap = capacity;map = new HashMap<>();cache = new DoubleList();}// Upgrade a key to the most recently usedprivate void makeRecently(int key) {Node x = map.get(key);// Delete this node from the linked list firstcache.remove(x);// Move back to the end of the linecache.addLast(x);}// Add the most recently used elementprivate void addRecently(int key, int val) {Node x = new Node(key, val);// The end of the list is the most recently used elementcache.addLast(x);// Add the mapping of the key to the mapmap.put(key, x);}// Delete a keyprivate void deleteKey(int key) {Node x = map.get(key);// Delete from the linked listcache.remove(x);// Delete from mapmap.remove(key);}// Delete the element that has been unused the longestprivate void removeLeastRecently() {// The first element at the head of the list is the one// that has been unused for the longest timeNode deletedNode = cache.removeFirst();// Delete its key from the mapint deleteKey = deletedNode.key;map.remove(deleteKey);}public int get(int key) {if (!map.containsKey(key)) {return -1;}// Upgrade the data to the most recently usedmakeRecently(key);return map.get(key).val;}public void put(int key, int value) {if (map.containsKey(key)) {// Delete old datadeleteKey(key);// The newly inserted data is the latest dataaddRecently(key, value);return;}if (cap == cache.size()) {// Delete the element that has been unused the longestremoveLeastRecently();}// Add as recently used elementaddRecently(key, value);}
}/*** Your LRUCache object will be instantiated and called as such:* LRUCache obj = new LRUCache(capacity);* int param_1 = obj.get(key);* obj.put(key,value);*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/640732.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【前后端】django前后端交互

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、django是什么二、django前后端交互指引三、总结 前言 随着开发语言及人工智能工具的普及&#xff0c;使得越来越多的人会主动学习使用一些开发语言&#x…

零售数据分析方案:深度剖析人、货、场

人&#xff0c;即会员分析、用户分析&#xff0c;通过分析获得直观的用户画像&#xff0c;了解目标用户群体的消费水平、喜好、频率&#xff0c;为销售营销决策提供必要的数据支持&#xff1b;货&#xff0c;即商品分析&#xff0c;包括但不限于分析商品结构、分析销售top10商品…

构建云原生湖仓:Apache Iceberg与Amoro的结合实践

随着大数据技术的快速发展&#xff0c;企业对数据的处理和分析需求日益增长。传统的数据仓库已逐渐无法满足现代业务对数据多样性和实时性的要求&#xff0c;这促使了数据湖和数据仓库的融合&#xff0c;即湖仓一体架构的诞生。在云原生技术的推动下&#xff0c;构建云原生湖仓…

Opensbi初始化分析:设备初始化

Opensbi初始化分析&#xff1a;设备初始化 设备初始化sbi_init函数coldinit&#xff0c;冷启动初始化sbi_scratch_init函数sbi_domain_init函数sbi_hsm_initsbi_platform_early_initsbi_hart_initsbi_console_initsbi_platform_irqchip_init中断控制器的初始化sbi_ipi_init函数…

C++奇迹之旅:从0开始实现日期时间计算器

文章目录 &#x1f4dd;前言&#x1f320; 头文件Date.h&#x1f309;日期计算函数&#x1f320;前后置&#x1f309;前后置-- &#x1f320;两对象日期相减&#x1f309;自定义流输入和输出 &#x1f309; 代码&#x1f309; 头文件Date.h&#x1f320;Date.cpp&#x1f309; …

数据挖掘实验(Apriori,fpgrowth)

Apriori&#xff1a;这里做了个小优化&#xff0c;比如abcde和adcef自连接出的新项集abcdef&#xff0c;可以用abcde的位置和f的位置取交集&#xff0c;这样第n项集的计算可以用n-1项集的信息和数字本身的位置信息计算出来&#xff0c;只需要保存第n-1项集的位置信息就可以提速…

在Qt creator中使用多光标

2024年4月22日&#xff0c;周一下午 Qt Creator 支持多光标模式。 多光标模式允许你在同一时间在多个光标位置进行编辑&#xff0c;从而可以更快地进行一些重复性的编辑操作。 要启用多光标模式&#xff0c;请按住 Alt 键&#xff0c;并用鼠标左键在文本编辑器中选择多个光标…

标题Selenium IDE 常见错误笔记

Selenium IDE 常见错误笔记 错误1&#xff1a;Failed:Exceeded waiting time for new window to appear 2000ms 这个错误通常出现在第一次运行时&#xff0c;有两个原因&#xff1a; Firefox阻止了弹出式窗口&#xff0c;在浏览器设置里允许这个操作即可。 有些网站设置了反…

Elasticsearch单机部署(Linux)

1. 准备环境 本文中Elasticsearch版本为7.12.0&#xff0c;JDK版本为1.8.0&#xff0c;Linux环境部署。 扩展&#xff1a; &#xff08;1&#xff09;查看Elasticsearch对应的常用的jdk版本如下&#xff1a;&#xff08;详情可看官网的支持一览表&#xff09; Elasticsearch a…

基于51单片机的电子秤LCD1602液晶显示( proteus仿真+程序+设计报告+讲解视频)

基于51单片机电子秤LCD显示 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真设计4. 程序代码5. 设计报告6. 设计资料内容清单&&下载链接 基于51单片机电子秤LCD显示( proteus仿真程序设计报告讲解视频&#xff09; 仿真图proteus8.9及以上 程序编译器&#xf…

基于SSM+Vue的护工预约服务小程序和后台管理系统

1、系统演示视频&#xff08;演示视频&#xff09; 2、需要请联系

五种服务异步通信(MQ)-详解、代码案例

简介&#xff1a;本篇文章主要是介绍了常用的异步通信原理&#xff0c;主要是RabbitMQ技术 目录 1、初始MQ&#xff08;异步通讯&#xff09; 1.1 同步通讯 1.2 异步通讯 1.3 MQ常见框架 2、RabbitMQ快速入门 2.1 RabbitMQ概述和安装 2.2 常见消息模型 2.3 快速入门 3、…