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实现:将节点移动到双链表最前面

相关推荐
To_OC3 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
旖-旎4 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
To_OC5 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
delishcomcn5 小时前
AI视觉识别+分切算法:电化铝缺陷检测与裁切一体化解锁
人工智能·算法
触底反弹6 小时前
深入理解大模型采样:Temperature、Top-K、Top-P 的原理与实战
人工智能·算法·面试
雪碧聊技术6 小时前
力扣 LCR 091. 粉刷房子 —— 动态规划入门详解
算法·动态规划
CV-Climber9 小时前
检索技术的实际应用
人工智能·算法
hhzz9 小时前
Tiger AI Platform平台中增加人脸识别功能
图像处理·人工智能·算法·计算机视觉·大模型
从零开始的代码生活_10 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法