LeetCode_0146. 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) 的平均时间复杂度运行。

分析

  1. get() 和 put() 操作需O(1)的时间按key查找 --> unordered_map
  2. 逐出LRU关键字需O(1)的时间 --> 需O(1)的时间维护容器内关键字的使用情况:hash定位后能O(1)的时间在增删移 --> 双向链表

设计

  • 维护一个双向链表list<pair<int, int>>,按上一次使用时间排列关键字和值,每次操作激活的键值对被移动到链表尾。
  • 维护一个哈希表unordered_map<int, list<pair<int, int>>::iterator>,映射关键字和链表中迭代器,每次对链表结点的插入/删除操作都要注意更新结点迭代器。因为list的迭代器不因其它元素的增删改而失效,可以这样持久保存。

实现

  class LRUCache {
  private:
      int capacity;
      unordered_map<int, list<pair<int, int>>::iterator> listIterMap;
      list<pair<int, int>> vkList;

  public:
      LRUCache(int _capacity) : capacity(_capacity) {}
      
      int get(int key) {
          auto lIt = listIterMap.find(key);
          if(lIt == listIterMap.end()) {
              return -1;
          }
          
          // 激活关键字:移动操作 = 删除 + 表尾插入
          pair<int, int> tmp = *(lIt->second);
          vkList.erase(lIt->second);
          lIt->second = vkList.insert(vkList.end(), tmp);

          return tmp.first;
      }
      
      void put(int key, int value) {
          auto lIt = listIterMap.find(key);
          if(lIt != listIterMap.end()) {
              (*(lIt->second)).first = value;
              pair<int, int> tmp = *(lIt->second);
              vkList.erase(lIt->second);
              lIt->second = vkList.insert(vkList.end(), tmp);
              return;
          }
          
          // 队满时删除表头
          if(vkList.size() == capacity) {
              int delKey = vkList.begin()->second;
              vkList.pop_front();
              listIterMap.erase(delKey);
          }
          
          // 在表尾插入新关键字
          auto nIt = vkList.insert(vkList.end(), make_pair(value, key));
          listIterMap.emplace(make_pair(key, nIt));

          return;
      }
  };
posted @ 2024-09-18 23:04  某糕  阅读(1)  评论(0编辑  收藏  举报