当前位置: 首页 > news >正文

力扣 hot100 Day41

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 ,则应该 逐出 最久未使用的关键字。

函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

//自己写的shit
class LRUCache {
public:LRUCache(int capacity) {max = capacity;num = 0;}int get(int key) {if (record.count(key)) {order[key] = 0;incrementOtherKeys(key);return record[key];}return -1;}void put(int key, int value) {if (record.count(key)) {record[key] = value;order[key] = 0;incrementOtherKeys(key);} else {record[key] = value;order[key] = 0;incrementOtherKeys(key);num++;if (num > max) {int max_order_key = -1;int max_order_value = -1;for (const auto& pair : order) {if (pair.second > max_order_value) {max_order_value = pair.second;max_order_key = pair.first;}}if (max_order_key != -1) {record.erase(max_order_key);order.erase(max_order_key);num--;}}}}private:unordered_map<int, int> record;unordered_map<int, int> order; int num;int max;void incrementOtherKeys(int key) {for (auto& pair : order) {if (pair.first != key) {pair.second++;}}}
};

这个代码过不了测试,超时,不过逻辑应该没问题

主要卡时间的地方在于,每次操作都需要更改order哈希表,这种记录新旧顺序的方法很烂

最优方法是使用双向链表

//抄的
class LRUCache {
private:int capacity;list<pair<int, int>> cache; unordered_map<int, list<pair<int, int>>::iterator> record; // 哈希表:键 -> 链表节点public:LRUCache(int capacity) : capacity(capacity) {}int get(int key) {auto it = record.find(key);if (it == record.end()) return -1;// 将节点移到链表头部(表示最近访问)cache.splice(cache.begin(), cache, it->second);return it->second->second;}void put(int key, int value) {auto it = record.find(key);if (it != record.end()) {// 更新值并移到链表头部it->second->second = value;cache.splice(cache.begin(), cache, it->second);} else {// 插入新节点到头部cache.emplace_front(key, value);record[key] = cache.begin();// 如果超限,删除尾部节点(最久未访问)if (record.size() > capacity) {record.erase(cache.back().first);cache.pop_back();}}}
};

官方题解是完全自己实现的双链表,这里用list更为简洁

 cache.splice(cache.begin(), cache, it->second);

splice用于移动节点,将it迭代器移动到链表头部,且时间复杂度为O(1)

http://www.dtcms.com/a/274221.html

相关文章:

  • OS16.【Linux】冯依诺曼体系结构和操作系统的浅层理解
  • 深度学习×第8卷:优化器与训练流程进阶——她开始跑起来,学着一次次修正自己
  • 聊聊AI大模型的上下文工程(Context Engineering)
  • linux网络编程之单reactor模型(一)
  • 渗透测试之木马后门实验
  • 笔记 | 理解C/汇编中的数组元素访问
  • UNIX 域套接字实现本地进程间通信
  • 【React Native】样式、网络请求和Loading
  • Hadoop 用户入门指南:驾驭大数据的力量
  • 【React Native】原生组件
  • Dify 1.5.0,1.5.1,1.6.0 新特性
  • 小旺AI截图×英特尔强强联合:AIPC生态开启智能生产力新纪元
  • C++设计秘籍:为什么所有参数都需类型转换时,非成员函数才是王道?
  • 基于强化学习的智能推荐系统优化实践
  • 继续Java的jpackage模块打包Linux可执行程序(包含第三方非模块化包)
  • 4G Cat.1 时代,如何选对 DTU?
  • IoC 是如何为 Spring 的其他核心功能(如 AOP、事务管理)提供基础支持的
  • openpilot:为您的汽车插上智能驾驶的翅膀
  • CV目标检测中的LetterBox操作
  • Swift 解 LeetCode 324:一步步实现摆动排序 II,掌握数组重排的节奏感
  • 使用自然语言体验对话式MySQL数据库运维
  • Claude Code:完爆 Cursor 的编程体验
  • UI前端大数据处理新趋势:基于边缘计算的数据处理与响应
  • 炎热工厂救援:算法打造安全壁垒
  • 对S32K144做的BMS安装快速开发Simulink库及BMS例程介绍
  • 【SpringBoot】 整合MyBatis+Postgresql
  • ROS1学习第三弹
  • uniApp实战五:自定义组件实现便捷选择
  • MyBatis缓存穿透深度解析:从原理到实战解决方案
  • Selenium 自动化实战技巧【selenium】