返回介绍

lcci / 16.25.LRU Cache / README_EN

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

16.25. LRU Cache

中文文档

Description

Design and build a "least recently used" cache, which evicts the least recently used item. The cache should map from keys to values (allowing you to insert and retrieve a value associ­ated with a particular key) and be initialized with a max size. When it is full, it should evict the least recently used item.

You should implement following operations:  get and put.

Get a value by key: get(key) - If key is in the cache, return the value, otherwise return -1.
Write a key-value pair to the cache: put(key, value) - If the key is not in the cache, then write its value to the cache. Evict the least recently used item before writing if necessary.

Example:


LRUCache cache = new LRUCache( 2 /* capacity */ );



cache.put(1, 1);

cache.put(2, 2);

cache.get(1);     // returns 1

cache.put(3, 3);  // evicts key 2

cache.get(2);     // returns -1 (not found)

cache.put(4, 4);  // evicts key 1

cache.get(1);     // returns -1 (not found)

cache.get(3);     // returns 3

cache.get(4);     // returns 4

Solutions

Solution 1

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 和您的相关数据。
    原文