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

【LeetCode】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) 的平均时间复杂度运行。

二、思路

LRU 意为 Latest Recently Used Cache,即 最近最少使用,既然是 使用,即 get 和 put 这两种操作均会让被操作的页优先级提高,从而不被淘汰。

为了实现优先级提高,常用的数据结构(数组、链表、队列、堆、栈、树),我们只能选择链表,因为只需要线性结构所以不选择树,因为需要改变节点顺序所以选择链表。通过链表即可实现将最近时间内最少被使用的页淘汰的特性。

为了实现 O(1)的时间复杂度,而选择的链表却是 O(N),因此需要哈希表的辅助。

链表和哈希表这两者怎么结合呢?通过让哈希表的值是链表节点的地址来实现。

即下图结构:

在这里插入图片描述

以leetocde的输入数据为例,说明具体执行过程:

首先,LRUCache lRUCache = new LRUCache(2);

其次,lRUCache.put(1, 1); 在 HashTable 放入 k = 1,v = *list.Element;List 中向Head端添加一个 *list.Element,值为 entry{k=1,v=1}。此时 List 为 {1=1}

lRUCache.put(2, 2); 在 HashTable 放入 k = 2,v = *list.Element;List 中向Head端添加一个 *list.Element,值为 entry{k=2,v=2}。此时 List 为 {2=2},{1=1}

lRUCache.get(1); 通过 k = 1,在 HashTable 中找到 *list.Element,返回其值为 entry{k=1,v=1}; 并将该 *List.Element 调整到 List 的 Head 位置处。并调整 HashTable 指向新 *list.Element。此时 List 为 {1=1},{2=2}

lRUCache.put(3, 3); 此时 List 为 {3=3},{1=1},将 {2=2}逐出List,并将{2=2}逐出HashTable。

lRUCache.get(2); 通过 HashTable 未查到则返回 -1。List 未改变。

lRUCache.put(4, 4); List 变为 {4=4},{3=3}

lRUCache.get(1); 通过 HashTable 未查到则返回 -1。List 未改变。

lRUCache.get(3); 通过 HashTable 查到,List 调整为 {3=3},{4=4}

lRUCache.get(4); 通过 HashTable 查到,List 调整为 {4=4},{3=3}

三、编码

type entry struct {k, v int}

type LRUCache struct {
    cap int
    mp  map[int]*list.Element
    lst *list.List
}


func Constructor(capacity int) LRUCache {
    return LRUCache{cap: capacity, mp: map[int]*list.Element{}, lst: list.New()}
}


func (this *LRUCache) Get(key int) int {
    e := this.mp[key]
    if e == nil {
        return -1
    }
    this.lst.MoveToFront(e)
    return e.Value.(entry).v
}


func (this *LRUCache) Put(key int, value int)  {
    if e := this.mp[key]; e != nil {
        e.Value = entry{k: key, v: value}
        this.lst.MoveToFront(e)
        return
    }
    this.mp[key] = this.lst.PushFront(entry{k: key, v: value})
    if len(this.mp) > this.cap {
        back := this.lst.Back()
        e := this.lst.Remove(back)
        delete(this.mp, e.(entry).k)
    }
}


/**
 * Your LRUCache object will be instantiated and called as such:
 * obj := Constructor(capacity);
 * param_1 := obj.Get(key);
 * obj.Put(key,value);
 */

相关文章:

  • 【JavaWeb项目】基于WebSocket的Web聊天室
  • File对象转MultipartFile 如何new出高仿MultipartFile对象
  • VScode配置运行C/C++、python,及快捷键配置
  • 【threejs】可视化大屏酷炫3D地图附源码
  • 安路FPGA学习备忘录
  • 目标检测算法——YOLOv5改进之结合MobileOne结构
  • Python之“诗词大会”游戏
  • MySQL:索引知识点盘点
  • 大神之路-起始篇 | 第9章.计算机科学导论之【程序设计语言】学习笔记
  • Python 的Tkinter包系列之四:对话框
  • 大神之路-起始篇 | 第8章.计算机科学导论之【数据算法】学习笔记
  • IDET变化检测模型
  • javascript基本语法(持续补充)
  • Spring Boot开发之Mybatis
  • 卷王杯 easy unserialize
  • 【Leetcode】104. 二叉树的最大深度
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • Android开源项目规范总结
  • canvas绘制圆角头像
  • JavaScript创建对象的四种方式
  • Js基础知识(四) - js运行原理与机制
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • Linux链接文件
  • Mysql数据库的条件查询语句
  • Python实现BT种子转化为磁力链接【实战】
  • React-生命周期杂记
  • Redis字符串类型内部编码剖析
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • windows下如何用phpstorm同步测试服务器
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 数组大概知多少
  • 微信小程序开发问题汇总
  • 智能合约Solidity教程-事件和日志(一)
  • Java数据解析之JSON
  • MPAndroidChart 教程:Y轴 YAxis
  • Nginx实现动静分离
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • # 达梦数据库知识点
  • (¥1011)-(一千零一拾一元整)输出
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (3)选择元素——(17)练习(Exercises)
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (六)Flink 窗口计算
  • (亲测有效)推荐2024最新的免费漫画软件app,无广告,聚合全网资源!
  • (算法)Game
  • (小白学Java)Java简介和基本配置
  • (原)本想说脏话,奈何已放下
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .net core 6 集成和使用 mongodb
  • .Net OpenCVSharp生成灰度图和二值图
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)