146. LRU 缓存

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。

实现 LRUCache 类:

  • LRUCache(int capacity)正整数 作为容量 capacity 初始化 LRU 缓存
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1
  • void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。

函数 getput 必须以 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

提示:

  • 1 <= capacity <= 3000
  • 0 <= key <= 10000
  • 0 <= value <= 105
  • 最多调用 2 * 105getput

class Node

{

public:

int value;

Node*pre;

Node*next;

Node(int v)

{

pre = nullptr;

next = nullptr;

value = v;

}

};

class LRUCache {

public:

LRUCache(int capacity) {

size = capacity;

}

private:

map<int, int>m;

int size;

map<int, Node*>m_l;

Node*cur = nullptr;

Node*head = nullptr;

int curSize = 0;

public:

Node* insertNode(int key)

{

Node* node = new Node(key);

if (cur == NULL)

{

head = node;

cur = node;

curSize++;

return node;

}

cur->next = node;

node->pre = cur;

cur = cur->next;

curSize++;

return node;

}

void deleteNode(Node*node)

{

if (nullptr != node->pre && nullptr != node->next)

{

node->pre->next = node->next;

node->next->pre = node->pre;

delete node;

node = nullptr;

curSize--;

return;

}

if (nullptr == node->pre && nullptr == node->next)

{

delete node;

node = nullptr;

cur = nullptr;

curSize--;

return;

}

//delete head

if (nullptr == node->pre)

{

head = node->next;

node->next->pre = nullptr;

delete node;

node = nullptr;

curSize--;

return;

}

//delete tail

if (nullptr == node->next)

{

node->pre->next = nullptr;

cur = node->pre;

delete node;

node = nullptr;

curSize--;

return;

}

}

//delete head

void deleteHead()

{

if (nullptr == head)

{

return;

}

if (nullptr == head->next)

{

curSize--;

delete head;

head = nullptr;

cur = nullptr;

return;

}

curSize--;

Node*tmp = head->next;

delete head;

tmp->pre = nullptr;

head = tmp;

}

public:

int get(int key) {

if (m.count(key))

{

Node *node = m_l[key];

deleteNode(node);

auto pos1 = m_l.find(key);

m_l.erase(pos1);

m_l[key] = insertNode(key);

return m[key];

}

else

{

return -1;

}

}

void put(int key, int value) {

if (m.count(key))

{

m[key] = value;

Node *node = m_l[key];

deleteNode(node);

auto pos1 = m_l.find(key);

m_l.erase(pos1);

m_l[key] = insertNode(key);

return;

}

if (curSize == size)

{

int tmp = head->value;

Node *node = m_l[tmp];

auto pos = m.find(tmp);

m.erase(pos);

deleteHead();

auto pos1 = m_l.find(tmp);

m_l.erase(pos1);

}

m[key] = value;

Node *node = m_l[key];

m_l[key] = insertNode(key);

}

};

相关推荐
聪明的笨猪猪17 分钟前
Java Redis “缓存设计”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
FIavor.17 分钟前
我发送给Apifox是http://localhost:9002/goods/getByUserName?name=张三 为什么会是500哪里错了?
java·服务器·网络协议·http
ID_1800790547318 分钟前
京东获取整站实时商品详情数据|商品标题|数据分析提取教程
java·开发语言
微露清风1 小时前
系统性学习C++-第五讲-内存管理
java·c++·学习
计算机毕业设计木哥1 小时前
计算机毕业设计选题推荐:基于SpringBoot和Vue的快递物流仓库管理系统【源码+文档+调试】
java·vue.js·spring boot·后端·课程设计
235161 小时前
【LeetCode】146. LRU 缓存
java·后端·算法·leetcode·链表·缓存·职场和发展
聪明的笨猪猪1 小时前
Java Redis “运维”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
FIavor.1 小时前
怎么办这是Apifox里执行http://localhost:9002/goods/getByUserName?name=“张三“为什么我改了还是500?
java·网络·网络协议·http
编程饭碗1 小时前
【Java集合】
java
岁岁岁平安1 小时前
Java的双重检查锁机制(DCL)与懒加载的单例模式
java·单例模式·synchronized·