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

相关推荐
lihao lihao2 小时前
OJ管理系统后端测试报告
算法
@insist1232 小时前
软件设计师-算法核心考点:五大特性与复杂度分析(含主定理)
算法·软考·软件设计师·软件水平考试
wuqingshun3141592 小时前
蓝桥杯 无影之谜
算法·职场和发展·蓝桥杯
ouliten2 小时前
C++笔记:std::hash
c++·笔记·哈希算法
武帝为此2 小时前
【专家系统介绍】
人工智能·算法
@insist1232 小时前
软件设计师-分治法核心原理与典型应用
算法·软考·软件设计师·软件水平考试
机器学习之心2 小时前
PSO-SVR粒子群算法优化支持向量机回归+SHAP分析+新数据预测,MATLAB代码
算法·支持向量机·回归·pso-svr·灰狼算法优化支持向量机回归
8Qi82 小时前
环形链表刷题笔记(LeetCode热题100--141、142)
c语言·数据结构·c++·算法·leetcode·链表
滴滴答滴答答2 小时前
机考刷题之 13 LeetCode 1004 最大连续1的个数 III
java·算法·leetcode