LRUCache缓存实现

python 复制代码
class Node:
    __slots__='key','value','next','prev'
    def __init__(self,key=0,value=0):
        self.key=key
        self.value=value

class LRUCache:
    def __init__(self,capacity):
        self.capacity=capacity
        self.key_to_node={}
        self.dummy=Node()
        self.dummy.next=self.dummy
        self.dummy.prev=self.dummy

        
    def get(self,key:int)->int:
        if key not in self.key_to_node:
            return -1
        #在哈希表里面
        node=self.key_to_node[key]  #拿到节点
        self.remove(node) #删除节点
        self.push_to_front(node) #移到最前面
        return node.value

    #新加入节点
    def put(self,key:int,value:int):
        if key in self.key_to_node:  #如果已经存在,就更新value
            node=self.key_to_node[key]  #拿到节点
            node.value=value  #更新值
            self.remove(node)  #在该位置删除元素
            self.push_to_front(node)   #把更新后的元素移动到最前面
        else: #如果节点不在里面,先检查容量,再插入
            if len(self.key_to_node)==self.capacity:  #容量满了,需要删除最久未使用元素
                #删除链表最后一个元素
                last=self.dummy.prev  #获取链表最后一个元素
                self.remove(last)   #移除元素
                del self.key_to_node[last.key]  #哈希表里删除该node
            new_node=Node(key,value)
            self.push_to_front(new_node)  #将新节点放到最前面
            self.key_to_node[key]=new_node  #加入到哈希表
  
    def remove(self,node):  #双链表删除元素操作,双链表断链
        node.prev.next=node.next
        node.next.prev=node.prev
        
    def push_to_front(self,node):  #头插法,将元素放到最前面
            node.prev=self.dummy
            node.next=self.dummy.next
            self.dummy.next.prev=node
            self.dummy.next=node

# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)

思路:双链表+哈希表(想象成一堆书,取书放书的过程):因为要求时间复杂度为O(1),所以需要想到使用哈希表;因为要删除某一个元素,可能是中间也可能是两端,所以使用双链表。

步骤:

1.哈希表结构:{key:node},初始化节点node:key,value;初始化双链表,新建哈希表

2.get实现:如果key不在哈希表中,返回-1:若在,则先记录下该节点,然后在原位置删除(remove),再将该节点移动到双链表最前面(push_to_front,因为用过一次,就表示该节点是最新使用的,需要放到最前面),最后返回node.value。

3.put实现:先检查哈希表中是否已经存在,若存在,则先拿到该节点,更新value,再删除该位置的node,并且将node移动到双链表最前面。若不存在,则先检查容量是否满了,满了就先删除双链表最后一个元素:首先拿到双链表最后一个元素,之后删除,然后还需要在哈希表中删除该节点。有了容量之后,存入新节点放到双链表最前面,还需要加入到哈希表中。

4.remove实现:双链表断链操作

5.push_to_front实现:将节点移动到双链表最前面

相关推荐
车压9 小时前
从“为什么”理解注意力机制
算法
wabs6669 小时前
关于哈希表【力扣15.三数之和的思考】
数据结构·算法·leetcode·散列表·哈希表·三数之和
退休倒计时9 小时前
【每日一题】LeetCode 88. 合并两个有序数组 TypeScript
算法·leetcode·职场和发展·typescript
键盘会跳舞10 小时前
C++:函数对象与 std::function 源码级深度拆解——泛型算法的策略内核与可调用对象统一封装
c++·算法·仿函数
手写码匠10 小时前
华为云Flexus+DeepSeek征文|Agent 评测体系实战:用 DeepSeek-R1 当裁判,打造 Dify Agent 的自动化回归测试流水线
人工智能·深度学习·算法·aigc
LONGZETECH10 小时前
无人机实训高成本痛点解法:虚拟仿真实现 70% 耗材损耗下降
大数据·算法·unity·架构·无人机
不会就选b10 小时前
算法日常・每日刷题--<队列,宽搜>4
算法
码字的特恩10 小时前
微软确认暂不为 Windows 11 加入透明效果自定义功能,建议用户使用第三方工具
人工智能·windows·算法·microsoft·计算机·大模型·编程
星轨初途10 小时前
LeetCode 热题 100——day10 和为 K 的子数组
开发语言·c++·算法·leetcode
数模竞赛Paid answer10 小时前
2021年深圳杯数学建模C题配电网可靠性和故障软自愈研究解题全过程论文及程序
算法·数学建模·数据分析·深圳杯