老卫带你学---leetcode刷题(146. LRU 缓存)

146. LRU 缓存

问题:

你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

示例:

输入
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]

解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1);    // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2);    // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1);    // 返回 -1 (未找到)
lRUCache.get(3);    // 返回 3
lRUCache.get(4);    // 返回 4
提示:

1 <= capacity <= 3000
0 <= key <= 10000
0 <= value <= 105
最多调用 2 * 105 次 get 和 put

解决:

用双向链表来存储数据,并且处理好最新访问的放到最后,以及容量控制

class Node:
  def __init__(self,key=None,val=None) -> None:
     self.key=key
     self.val=val
     self.pre=None
     self.next=None
     
     
class LRUCache:

    def __init__(self, capacity: int):
      self.capacity=capacity
      self.hashmap={}
      self.head=Node()
      self.tail=Node()
      
      self.head.next=self.tail
      self.tail.pre=self.head

    def move_to_tail(self,key)->None:
      node:Node = self.hashmap[key]
      node.next.pre=node.pre ## 移除node
      node.pre.next=node.next
      
      node.next=self.tail
      node.pre=self.tail.pre
      self.tail.pre.next=node
      self.tail.pre=node

    def get(self, key: int) -> int:
      r = self.hashmap.get(key,-1)
      if r==-1:
        return -1
      else:
        self.move_to_tail(key)
        return r.val

      

    def put(self, key: int, value: int) -> None:
      if key in self.hashmap:
        self.hashmap[key].val=value
        self.move_to_tail(key)
      else:
        ## 插入新的前,先检查是否大于capacity
        if len(self.hashmap)>=self.capacity:
          self.hashmap.pop(self.head.next.key)
          self.head.next =self.head.next.next
          self.head.next.pre=self.head
        node = Node(key,value)
        self.hashmap[key]=node
        node.next=self.tail
        node.pre=self.tail.pre
        self.tail.pre.next=node
        self.tail.pre=node

你可能感兴趣的:(leetcode,缓存)