LC的Shopee面试题库最高频率题LRU缓存|刷题打卡

988 阅读1分钟

一、题目描述:

1Q{NC5905G%E~B6ODC{F.png

二、思路分析:

先写个普通版本,首先要保证删除最久未使用,因此设置一个vector,保存已经存储的队列,其次设置当前容量和最大容量,由于get需要得到value值,put也需要比较key值来确定是否应该添加元素,因此设置个map

class LRUCache {
public:
    vector<int> qe;
    map<int,int> mp;
    int ca;
    int ta;
    LRUCache(int capacity) {
        ta = 0;
        ca = capacity;
    }
    
    int get(int key) {
        if(mp.find(key) == mp.end()){
            return -1;
        }else{
            for(int  i = 0; i < qe.size(); i++)
            if(qe[i] == key)qe.erase(qe.begin() + i);
            qe.push_back(key);
            return mp[key];
        }
    }
    
    void put(int key, int value) {
        if(mp.find(key) == mp.end()){
            if(ta == ca){
                //manle
                mp.erase(qe[0]);
                qe.erase(qe.begin());
                qe.push_back(key);
                mp[key] = value;
                
            }else{
                ta++;
                
                mp[key] = value;
                qe.push_back(key);
            }
        }else{
            mp[key] = value;
            for(int i = 0; i < qe.size(); i++){
                if(qe[i] == key)qe.erase(qe.begin() + i);
            }
            qe.push_back(key);
        }
        
    }
};

/**
 * 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);
 */

但题目要求我们put和get方法都是O(1)完成的

我们看到耽误时间的是在vector查找耽误时间

因此我们需要在vector的基础上,进行快速查找

可以通过HashMap将hash查找的优点和Vector链接起来,让Hash直接对应key在vector存储的位置 【但C++ vector是用数组实现的,因此在删除元素时会改变位置,所以改用为List】

class LRUCache {
private:
  list<pair<int, int>> cache;   ////< @note pair[key]=value
  unordered_map<int, list<pair<int, int>>::iterator> key2node;
  int cap;                      ////< @note 最大容量

public:
  LRUCache(int capacity) : cap(capacity) {}

  int get(int key) {
    if (key2node.find(key) == key2node.end()) {
      return -1;
    }
    pair<int, int> node = *key2node[key];
    cache.erase(key2node[key]); ////< @note 将节点移到链表头部并更新map
    cache.push_front(node);
    key2node[key] = cache.begin();
    return node.second;
  }

  void put(int key, int val) {
    auto newNode = std::make_pair(key, val);

    if (key2node.count(key)) {  ////< @note 若该节点已存在,则删除旧的节点
      cache.erase(key2node[key]);
    } else {
      if (cap == cache.size()) {
        key2node.erase(cache.back().first);
        cache.pop_back();       ////< @note 删除链表最后一个数据
      }
    }

    cache.push_front(newNode);  ////< @node 插入新的节点到头部
    key2node[key] = cache.begin();
  }
};

/**
 * 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);
 */


三、总结:

这道题是LC的Shopee面试题库最高频率题,并没有使用xx算法,顶多是考验我们对数据结构的理解,从需求中分析出需要快速查找是第一步,如何根据分析的结果,大胆的设计出合适的数据结构才是重中之重。

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情