首页 > 其他分享 >LeetCode - #146 LRU 缓存(Top 100)

LeetCode - #146 LRU 缓存(Top 100)

时间:2024-11-28 19:33:17浏览次数:9  
标签:146 node get Int Top LRU key put lRUCache

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

文章目录

前言

本题为 LeetCode 前 100 高频题

我们社区陆续会将顾毅(Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。

LeetCode 算法到目前我们已经更新到 145 期,我们会保持更新时间和进度(周一、周三、周五早上 9:00 发布),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。

不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。

难度水平:中等

1. 描述

请你设计并实现一个满足 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) 的平均时间复杂度运行。

2. 示例

示例 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 <= 10^5
  • 最多调用 2 * 10^5getput

3. 答案

class LRUCache {

    private let capacity: Int
    private var count = 0

    private let head = LRUCacheNode(0, 0)
    private let tail = LRUCacheNode(0, 0)

    private var dict = [Int: LRUCacheNode]()

    init(_ capacity: Int) {
        self.capacity = capacity

        head.next = tail
        tail.pre = head
    }

    func get(_ key: Int) -> Int {
        if let node = dict[key] {
            remove(key)
            insert(node)
            return node.val
        }
        return -1
    }

    func put(_ key: Int, _ value: Int) {
        if let node = dict[key] {
            node.val = value
            remove(key)
            insert(node)
            return
        }

        let node = LRUCacheNode(key, value)
        dict[key] = node
        if count == capacity, let tailKey = tail.pre?.key {
            remove(tailKey)
        }
        insert(node)
    }

    private func insert(_ node: LRUCacheNode) {
        dict[node.key] = node

        node.next = head.next
        head.next?.pre = node
        node.pre = head
        head.next = node

        count += 1
    }

    private func remove(_ key: Int) {
        guard count > 0, let node = dict[key] else {
            return
        }
        dict[key] = nil

        node.pre?.next = node.next
        node.next?.pre = node.pre
        node.pre = nil
        node.next = nil

        count -= 1
    }

}

fileprivate class LRUCacheNode {

    let key: Int
    var val: Int

    var pre: LRUCacheNode?
    var next: LRUCacheNode?

    init(_ key: Int, _ val: Int) {
        self.key = key
        self.val = val
    }

}
  • 主要思想:使用链表和哈希映射来构建缓存。
  • 时间复杂度: O(1)
  • 空间复杂度: O(k)

该算法题解的仓库:LeetCode-Swift

点击前往 LeetCode 练习

关于我们

我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。

标签:146,node,get,Int,Top,LRU,key,put,lRUCache
From: https://blog.csdn.net/qq_36478920/article/details/144118701

相关文章

  • RAG实验:块大小分割实验、矢量存储;FAISS 与 Chroma、向量存储和 Top k、向量存储中的距
    比较RAG第1部分:块大小分割实验我探索了RAG模型中的各种块大小,并使用专为评估检索器组件而设计的RAGAS评估器对其进行了评估。如您所知,检索器部分会生成随后输入到语言模型(LLM)中的“上下文”。在这个实验中,我采用了BGE作为嵌入技术(它在HuggingFace的排行榜上得分......
  • 修改docker desktop镜像下载目录
    选用dockerdesktop版本为4.31.1.0使用Hyper-v安装 点击Browse按钮选择镜像存放的位置,选择位置后会自动在所选的目标目录后拼上DockerDesktop路径,所以在选择完目录后需要手动在目标目录中创建DockerDesktop文件夹。如果没有手动创建DockerDesktop文件夹会有以下报错。所......
  • 行业专家推荐2024年CRM系统Top 5
    商业环境瞬息万变,客户关系管理(CRM)系统帮助企业更好地连接客户、理解客户、服务客户,已成为企业不可或缺的战略资产。企业在选择CRM系统时,应做好充分的市场调查。为了帮助企业更好地把握市场机遇,提升客户体验,本文根据搜索结果和行业专家的评价,推荐2024年各方面排名靠前的5个CRM系统......
  • stopPropagation()和preventDefault()这两个方法有什么区别?
    stopPropagation()和preventDefault()是JavaScript中用于事件处理的两个重要方法,它们的主要区别在于它们针对事件的不同方面:stopPropagation()阻止事件冒泡:当一个元素上的事件被触发时,例如点击一个按钮,该事件会沿着DOM树向上冒泡,触发其父元素、祖先元素上的相同事件......
  • OWASP TOP 10漏洞总结
    A01权限控制失效1.概述在Web应用系统中,由于权限控制机制未能正确实施或存在缺陷,导致用户能够访问或操作他们本不应该具备权限的资源或功能。这种情况通常发生在系统未能遵循最小权限原则或默认拒绝原则。2.危害未认证信息泄露:攻击者可以访问未经授权的信息,例如其他用户......
  • Time Stop#NOIP2024/GDUTCPC
    重要声明:本文章从2024.11.2716:12开始落笔,故cnblogs平台显示的上传时间会在NOIP2024比赛之前。本文章作者不存在任何以各类非合法渠道提前获取NOIP2024比赛题目的可能,同时也没有将该想法实现对应的资源或权力。请各位读者作证,并请相关组织明察。Day-3/2024.11.27这......
  • Redis LRU算法和LFU算法
    Redis的近似LRU和LFU算法基本概念Least:最小、最少LRU(LeastRecentlyUsed)全称是最近最少使用LFU全称是最少使用算法(LeastFrequentlyUsed:使用频率最少)标准LRU算法实现原理:使用链表存储元素并按照一定的顺序进行排列。当空间满的时候,会踢掉链表尾部的元素。当某个元......
  • 【北京迅为】itop-3562开发板在Linux系统中使用NPU
     3.1在Linux系统中使用NPU下载rknpu2并拷贝到虚拟机Ubuntu,如下图所示,RKNPU2提供了访问RK3562芯片NPU的高级接口。   下载地址为“iTOP-RK3562开发板\02_【iTOP-RK3562开发板】开发资料\12_NPU使用配套资料\01_rknpu2工具”对于RK3562来说,Linux平......
  • MITRE公布2024 年“CWE TOP 25”
    MITRE分享了从2023年6月至2024年6月期间披露的31,000多个漏洞背后最常见和最危险的25个软件弱点列表。软件弱点是指在软件的代码、架构、实现或设计中发现的缺陷、错误、漏洞和错误。攻击者可以利用这些弱点来破坏运行易受攻击软件的系统,从而能够控制受影响的设备并......
  • RabbitMQ5:Fanout交换机、Direct交换机、Topic交换机
    欢迎来到“雪碧聊技术”CSDN博客!在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将不断探索Java的深邃世界,分享最新的技术动态、实战经验以及项目......