leetcode hot100 LRU缓存

devtools/2024/12/27 17:25:59/

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

class ListNode(object):

    def __init__(self,key,val,next=None,prev=None):

        self.val =val

        self.key = key

        self.next = next

        self.prev = prev



 

class LRUCache(object):

    def __init__(self, capacity):

        """

        :type capacity: int

        """

        self.capacity = capacity

        self.head = ListNode(-1,-1,None,None)

        self.tail = ListNode(-1,-1,None,None)

        self.head.next=self.tail

        self.tail.prev = self.head

        self.num_nodes = 0

        self.hashmap={}

        # 应该是保存key :node node里面是val

    def remove_to_tail(self,rt):

        rt.prev.next = rt.next

        rt.next.prev = rt.prev

       

        # 放到末尾,这里有点问题,应为删除的可能就是末尾

        prev = self.tail.prev

        prev.next = rt

        rt.next = self.tail

        self.tail.prev = rt

        rt.prev = prev

    def get(self, key):

        """

        :type key: int

        :rtype: int

        """

        # 转移到链表的尾部

        rt = self.hashmap.get(key,-1)

        if rt==-1:

            # 找不到的话,那就return -1

            return -1

        else:

            # 能找到就找到并且放到末尾

            # 删除原本的,然后放到末尾

            #  如果是末尾的话,根本不用动

            if rt==self.tail.prev:

                return rt.val

            else:

                # 删除原本的

                self.remove_to_tail(rt)

                return rt.val

       

    def put(self, key, value):

        """

        :type key: int

        :type value: int

        :rtype: None

        """

        if  self.hashmap.get(key):

            # print(1111111)

            self.hashmap[key].val = value

            # 然后放到tail去

            rt = self.hashmap[key]

            # 删除原本的

            self.remove_to_tail(rt)


 

        else:

            temp = ListNode(key,value)

            if self.num_nodes<self.capacity:

                self.hashmap[key]=temp

               

               

                prev = self.tail.prev

                prev.next = temp

                temp.next = self.tail

                self.tail.prev = temp

                temp.prev = prev

                self.num_nodes+=1

            else:

                # >=cap,也就是需要我们来删除一个

                # 删除头结点的下一个节点

                dele = self.head.next

                self.head.next = dele.next

                dele.next.prev = self.head

                # hashmap里面也要删除

                # print(self.hashmap)

                # print(dele.key)

                del self.hashmap[dele.key]

                # 删除之后加上最新的到为节点

                self.hashmap[key]=temp

                prev = self.tail.prev

                prev.next = temp

                temp.next = self.tail

                self.tail.prev = temp

                temp.prev = prev

                # 如果input的是相同的key会覆盖掉,这个时候num_nodes-1

                if key == dele.key:

                    self.num_nodes-=1






 

       


 

# Your LRUCache object will be instantiated and called as such:

# obj = LRUCache(capacity)

# param_1 = obj.get(key)

# obj.put(key,value)

这里我们的思路是,放入需要o1那么直接的我们使用hashmap,key是key value是list节点,同时节点要存储key和value,因为要通过节点进行删除,如果只有value,那就无法再hashmap之中删除

根据LRU的规律我们选择双向链表,因为单向的没有prev和next,无法进行删除操作

需要对于LRU算法非常熟悉才行啊,比如说

插入的时候:

        如果没到存储上限,那就直接放到最近使用

        如果到达存储上限,那就删除掉最远的,放到最近使用

        如果插入的是已经有的,那就把原本的换成现在的,并且放到最近使用

查询:

        如果查询到了,把原本节点删除,新节点直接放到最近使用

一些细节:必须要有两个伪装节点head tail因为如果这两个不单独创建的话,删除的时候tail很可能被删除,不好写


http://www.ppmy.cn/devtools/145878.html

相关文章

C语言学习笔记(2)

在学习前&#xff0c;需要有一定的C语言基础。不必很深入&#xff0c;只需要知道函数&#xff0c;头文件&#xff0c;指针&#xff0c;数组等的概念就可以&#xff0c;但并非0基础笔记。 由于写到后面&#xff0c;不好编辑了&#xff0c;决定分成多篇写&#xff0c;请按编号学…

【扩展卡尔曼滤波理论推导与实践】【理论】【2/3 公式推导】

目录 非线性系统泰勒展开卡尔曼滤波卡尔曼增益模型误差协方差矩阵 公式总结 本节默认你能够完整推导标准卡尔曼滤波&#xff0c;将会简化一些推导的描述。如果你还不会完整推导标准卡尔曼滤波&#xff0c;请先从 【卡尔曼滤波理论推导与实践】系列开始看起。 非线性系统 扩展…

2. FPGA基础了解--全局网络

前言 引入扇出的概念介绍FPGA中的全局网络为后续时序优化埋下伏笔 扇出 在FPGA设计中扇出是一个重要的概念&#xff0c;所谓的扇出就是一个控制信号所能控制的数据信号的总个数&#xff0c;比如ctrl信号的扇出就是16 reg ctrl 0; reg [15:0] out 0; always (posedge c…

php时间strtotime函数引发的问题 时间判断出错

在 PHP 中&#xff0c;strtotime 函数能处理的最大时间范围取决于您的系统和 PHP 版本。 一般来说&#xff0c;它可以处理的时间范围从 1901 年 12 月 13 日到 2038 年 1 月 19 日。超过这个范围可能会导致不可预测的结果或错误。 如果您需要处理更大范围的时间&#xff0c;可能…

跟着 8.6k Star 的开源数据库,搞 RAG!

过去 9 年里&#xff0c;HelloGitHub 月刊累计收录了 3000 多个开源项目。然而&#xff0c;随着项目数量的增加&#xff0c;不少用户反馈&#xff1a;“搜索功能不好用&#xff0c;找不到想要的项目&#xff01;” 这让我意识到&#xff0c;仅仅收录项目是不够的&#xff0c;还…

Unity设置中文

安装好Unity Hub&#xff0c;下载好Unity后点击后面的小齿轮添加模块 选择简体中文安装&#xff0c;我已经安装好了 进入Unity编辑器 - 菜单上 Edit - Preference - Language - 选择 简体中文 这样编辑器就是中文版的了

gitlab设置ssh密钥,并考虑已经有其他仓库(如在github等)密钥的情况(多密钥配置问题)

直接clone失败 注意配置用户名和email git config --global user.name yournamegit config --global user.email youremail#查看所有配置信息 git config --list 创建密钥&#xff08;注意&#xff09; 命令&#xff1a;ssh-keygen -t rsa -b 4096 -C "your_emailexampl…

【 CSS 】sass 扩展语言的安装

一、全局安装node-sass Sass世界上最成熟、稳定和强大的CSS扩展语言 | Sass中文网 https://www.npmjs.com/package/node-sass NPM镜像_NPM下载地址_NPM安装教程-阿里巴巴开源镜像站 注意&#xff1a;nodejs版本14以上&#xff0c;否则node-sass安装不成功 npm install -g mi…