【力扣100】146.LRU缓存

添加链接描述

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


class LRUCache:

    def __init__(self, capacity: int):
        self.cache = dict()
        # 使用伪头部和伪尾部节点    
        self.head = DLinkedNode()
        self.tail = DLinkedNode()
        self.head.next = self.tail
        self.tail.prev = self.head
        self.capacity = capacity
        self.size = 0

    def get(self, key: int) -> int:
        if key not in self.cache:
            return -1
        # 如果 key 存在,先通过哈希表定位,再移到头部
        node = self.cache[key]
        self.moveToHead(node)
        return node.value

    def put(self, key: int, value: int) -> None:
        if key not in self.cache:
            # 如果 key 不存在,创建一个新的节点
            node = DLinkedNode(key, value)
            # 添加进哈希表
            self.cache[key] = node
            # 添加至双向链表的头部
            self.addToHead(node)
            self.size += 1
            if self.size > self.capacity:
                # 如果超出容量,删除双向链表的尾部节点
                removed = self.removeTail()
                # 删除哈希表中对应的项
                self.cache.pop(removed.key)
                self.size -= 1
        else:
            # 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
            node = self.cache[key]
            node.value = value
            self.moveToHead(node)
    
    def addToHead(self, node):
        node.prev = self.head
        node.next = self.head.next
        self.head.next.prev = node
        self.head.next = node
    
    def removeNode(self, node):
        node.prev.next = node.next
        node.next.prev = node.prev

    def moveToHead(self, node):
        self.removeNode(node)
        self.addToHead(node)

    def removeTail(self):
        node = self.tail.prev
        self.removeNode(node)
        return node

思路:

  1. 这道题的题目理解:
  • 1)当使用get命令时,如果无,则返回-1;如果有则先在哈希表中查找这个值,返回值的同时,这个节点移到最前面(因为被访问过了,就排在前面)
  • 2)当使用put命令时,先在哈希表里查找这个值,如果有,则把这个节点的值做更改,然后把这个节点放到前面;如果没有,则先在哈希表中添加这个节点,然后把这个节点放进链表中;同时这里要注意,控制链表的长度,如果大于指定长度,则把尾结点指向的值弹出,同时还要把弹出的节点从哈希表里删掉 self.cache.pop(removed.key)
  1. 然后需要添加的四个函数:
  • 添加指定值节点
  • 删除指定值节点
  • 指定值节点移到头部:先删除指定值,再添加指定值
  • 超出长度后,删除尾结点节点这个函数需要返回值,因为要在哈希表中删除对应的键值对,这里也对应了为什么我在构建节点时需要把key和value都保存在节点里,因为哈希表删除需要给出**键**
相关推荐
m0_62949473几秒前
LeetCode 热题 100-----27. 合并两个有序链表
数据结构·算法·leetcode·链表
玖釉-几秒前
Slang 和 HLSL 的区别与用法详解:现代图形渲染中的两种 Shader 编程语言
c++·算法·图形渲染
t-think2 分钟前
深入了解指针(3)
c语言·算法
GIOTTO情2 分钟前
Infoseek 危机公关自动化闭环系统,实现 PR 运维工程化
人工智能·算法·机器学习
hef2883 分钟前
利用C 图形界面展示MATLAB算法的高效混合编程实践
windows·算法·matlab
sali-tec4 分钟前
C# 基于OpenCv的视觉工作流-章76-轮廓-段距
图像处理·人工智能·opencv·算法·计算机视觉
水木流年追梦5 分钟前
大模型入门-RL基础
开发语言·python·算法·leetcode·正则表达式
城事漫游Molly13 分钟前
AI 快速生成标准化问卷分析报告:从 SUS 到 UMUX-LITE,如何把“分数”写成“结论”
人工智能·算法·机器学习·论文笔记·科研统计·问卷设计
人道领域18 分钟前
【LeetCode刷题日记】617.合并二叉树(空间换安全,还是原地省内存)
java·数据结构·算法·leetcode
MRSM_0121 分钟前
Redis 缓存、队列、排行榜的核心用法
数据库·redis·缓存