返回介绍

lcci / 16.25.LRU Cache / README

发布于 2024-06-17 01:04:42 字数 4353 浏览 0 评论 0 收藏 0

面试题 16.25. LRU 缓存

English Version

题目描述

设计和构建一个“最近最少使用”缓存,该缓存会删除最近最少使用的项目。缓存应该从键映射到值(允许你插入和检索特定键对应的值),并在初始化时指定最大容量。当缓存被填满时,它应该删除最近最少使用的项目。

它应该支持以下操作: 获取数据 get 和 写入数据 put

获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。

示例:

LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);     // 返回  1
cache.put(3, 3);  // 该操作会使得密钥 2 作废
cache.get(2);     // 返回 -1 (未找到)
cache.put(4, 4);  // 该操作会使得密钥 1 作废
cache.get(1);     // 返回 -1 (未找到)
cache.get(3);     // 返回  3
cache.get(4);     // 返回  4

解法

方法一

class Node:
  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 = {}
    self.head = Node()
    self.tail = Node()
    self.capacity = capacity
    self.size = 0
    self.head.next = self.tail
    self.tail.prev = self.head

  def get(self, key: int) -> int:
    if key not in self.cache:
      return -1
    node = self.cache[key]
    self.move_to_head(node)
    return node.value

  def put(self, key: int, value: int) -> None:
    if key in self.cache:
      node = self.cache[key]
      node.value = value
      self.move_to_head(node)
    else:
      node = Node(key, value)
      self.cache[key] = node
      self.add_to_head(node)
      self.size += 1
      if self.size > self.capacity:
        node = self.remove_tail()
        self.cache.pop(node.key)
        self.size -= 1

  def move_to_head(self, node):
    self.remove_node(node)
    self.add_to_head(node)

  def remove_node(self, node):
    node.prev.next = node.next
    node.next.prev = node.prev

  def add_to_head(self, node):
    node.next = self.head.next
    self.head.next.prev = node
    self.head.next = node
    node.prev = self.head

  def remove_tail(self):
    node = self.tail.prev
    self.remove_node(node)
    return node


# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
class LRUCache {
  class Node {
    int key;
    int value;
    Node prev;
    Node next;
    Node() {
    }
    Node(int key, int value) {
      this.key = key;
      this.value = value;
    }
  }

  private Map<Integer, Node> cache;
  private Node head;
  private Node tail;
  private int capacity;
  private int size;

  public LRUCache(int capacity) {
    cache = new HashMap<>();
    this.capacity = capacity;
    head = new Node();
    tail = new Node();
    head.next = tail;
    tail.prev = head;
  }

  public int get(int key) {
    if (!cache.containsKey(key)) {
      return -1;
    }
    Node node = cache.get(key);
    moveToHead(node);
    return node.value;
  }

  public void put(int key, int value) {
    if (cache.containsKey(key)) {
      Node node = cache.get(key);
      node.value = value;
      moveToHead(node);
    } else {
      Node node = new Node(key, value);
      cache.put(key, node);
      addToHead(node);
      ++size;
      if (size > capacity) {
        node = removeTail();
        cache.remove(node.key);
        --size;
      }
    }
  }

  private void moveToHead(Node node) {
    removeNode(node);
    addToHead(node);
  }

  private void removeNode(Node node) {
    node.prev.next = node.next;
    node.next.prev = node.prev;
  }

  private void addToHead(Node node) {
    node.next = head.next;
    head.next.prev = node;
    head.next = node;
    node.prev = head;
  }

  private Node removeTail() {
    Node node = tail.prev;
    removeNode(node);
    return node;
  }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文