146. LRU 缓存

  1. 题目链接

  2. 解题思路:用链表+哈希表。链表从头串到尾,淘汰时,从尾部开始淘汰。每次get时,如果找到了,则把这个节点移到头部。每次put,新建一个节点,放在头部,如果容量不够了,则淘汰尾部的数据。哈希表的作用是,能快速通过key找到链表中的节点。

  3. 代码

    class LRUCache:
    
        class Node:
            def __init__(self, key, val):
                self.key = key
                self.val = val
                self.pre = None
                self.next = None
    
        def __init__(self, capacity: int):
            self.capacity = capacity   # LRU缓存大小
            self.head = None     # 链表头
            self.tail = None     # 链表尾
            self.size = 0        # 当前节点数目
            self.dict = {}       # 节点的位置:int-Node      通过编号 找到Node
    
        def get(self, key: int) -> int:
            res = self.dict.get(key)
            if res == None:    # 没有找到
                return -1
            # 找到了    要放到链表头去   注意,如果刚好是链表尾,那么链表尾也要调整
            if self.size == 1 or self.head == res:   # 只有一个节点或者就是头节点  不用调整
                return res.val
            if res == self.tail:
                self.tail = res.pre
            pre = res.pre
            next = res.next
            if pre:
                pre.next = next
            if next:
                next.pre = pre
            res.next = self.head
            self.head.pre= res
            res.pre = None
            self.head = res
            return res.val
            
    
        def put(self, key: int, value: int) -> None:
            res = self.dict.get(key)
            if res == None:   # 没有找到
                # 创建新的节点   放在头
                new_node = self.Node(key, value)
                new_node.next = self.head
                self.dict[key] = new_node
                if self.head:
                    self.head.pre = new_node
                self.head = new_node
                if self.tail == None:  
                    self.tail = self.head
    
    
                if self.size >= self.capacity:   # 超出容量大小了   把尾部的删除了
                    self.dict.pop(self.tail.key)    # 要从哈希表中移除
                    self.tail = self.tail.pre
                    if self.tail:
                        self.tail.next = None
                else:
                    self.size += 1
            else:  # 找到了
                res.val = value
                self.get(key)   # 调用get函数,自动把node移动到链表头
    
posted @ 2024-12-27 16:35  ouyangxx  阅读(17)  评论(0)    收藏  举报