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

相关推荐
倒头就睡的小比特1 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼1 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光1 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark1 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her11 天前
并查集-听课笔记
笔记·算法·并查集
码流子1 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven1 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark1 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218611 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法