力扣146. LRU 缓存

news/2024/9/23 14:17:57/

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.ppmy.cn/news/1438301.html

相关文章

【树莓派4B】如何点亮树莓派的LED灯

在之前一系列文章中&#xff0c;使用python、行人入侵检测&#xff0c;确没有使用树莓派的硬件。控制引脚进行输出&#xff1a; 如何写python点亮led灯闪烁&#xff0c;我灯接在gpio13,GPIO19,gpio26。我都想闪烁。 你可以使用Python的GPIO库来控制树莓派上的LED灯。首先&…

提升你的C编程技能:使用cURL下载Kwai视频

概述 本文将介绍如何利用C语言以及cURL库来实现Kwai视频的下载。cURL作为一个功能强大的网络传输工具&#xff0c;能够在C语言环境下轻松地实现数据的传输。我们还将探讨如何运用代理IP技术&#xff0c;提升爬虫的匿名性和效率&#xff0c;以适应Kwai视频平台的发展趋势。 正…

STM32之串口中断接收丢失数据

五六年没搞STM32了&#xff0c;这个项目一切都挺顺利&#xff0c;万万没想到被串口接收中断恶心到了。遇到的问题很奇怪 HAL_UART_Receive_IT(&huart1, &rx_buffer[rx_index], LCD_UART_LEN); 这个代码中 LCD_UART_LEN1的时候&#xff0c;接收过来的数据&#xff0c;数…

德思特车载天线方案:打造智能互联的公共安全交通网络

作者介绍 一、方案介绍 随着自动驾驶与智慧汽车概念的逐步推进&#xff0c;人们对汽车的交互性、智能性、互联性有了更高的要求。今天&#xff0c;大多数汽车制造商和供应商普遍将GNSS定位功能与其他信号如广播、电视、蓝牙、Wifi一起集成到汽车中&#xff0c;包括博世、大陆、…

Kotlin语法入门-数据类、伴生类、枚举类(9)

Kotlin语法入门-数据类、伴生类、枚举类(9) 文章目录 Kotlin语法入门-数据类、伴生类、枚举类(9)九、数据类、伴生类、枚举类1、数据类2、伴生类2.1、定义伴生类2.2、JvmStatic注解2.3、const关键字 3、枚举类3.1、定义3.2、传参3.3、继承与实现 九、数据类、伴生类、枚举类 1…

nvm管理多个node版本,快速来回切换node版本

前言 文章基于 windows环境 使用nvm安装多版本nodejs。 最近公司有的项目比较老需要降低node版本才能运行&#xff0c;由于来回进行卸载不同版本的node比较麻烦&#xff1b;所以需要使用node工程多版本管理&#xff0c;后面自己就简单捯饬了一下nvm来管理node&#xff0c;顺便…

轻松搭建Rsync服务,实现高效文件同步

&#x1f6a9;本文介绍 在信息化快速发展的今天&#xff0c;文件同步的需求日益显著&#xff0c;无论是在企业内部的文件共享&#xff0c;还是在跨地域的数据备份&#xff0c;高效的文件同步都是不可或缺的一环。而Rsync作为一种快速、增量、远程&#xff08;和本地&#xff0…

Excel vlookup函数的使用教程 和 可能遇到的错误解决方法

使用VLOOKUP示例 被查询的表格 表一 A列B列C列A1aB2bC3c 要匹配的列 表二 F列G列H列ACBDA 要G列匹配字母&#xff0c;H列匹配数字 G 使用公式VLOOKUP(F5,A:D,3,0) 参数说明 F5 是表二 F列第五行的A A:D表是要匹配的数据列表在A到D列&#xff0c;就是表一 &#xff08;注意…