列表

详情


BM100. 设计LRU缓存结构

描述

设计LRU(最近最少使用)缓存结构,该结构在构造时确定大小,假设大小为 capacity ,操作次数是 n ,并有如下功能:
1. Solution(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
2. get(key):如果关键字 key 存在于缓存中,则返回key对应的value值,否则返回 -1 。
3. set(key, value):将记录(key, value)插入该结构,如果关键字 key 已经存在,则变更其数据值 value,如果不存在,则向缓存中插入该组 key-value ,如果key-value的数量超过capacity,弹出最久未使用的key-value

提示:
1.某个key的set或get操作一旦发生,则认为这个key的记录成了最常使用的,然后都会刷新缓存。
2.当缓存的大小超过capacity时,移除最不经常使用的记录。
3.返回的value都以字符串形式表达,如果是set,则会输出"null"来表示(不需要用户返回,系统会自动输出),方便观察
4.函数set和get必须以O(1)的方式运行
5.为了方便区分缓存里key与value,下面说明的缓存里key用""号包裹
数据范围:




示例1

输入:

["set","set","get","set","get","set","get","get","get"],[[1,1],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]],2

输出:

["null","null","1","null","-1","null","-1","3","4"]

说明:

我们将缓存看成一个队列,最后一个参数为2代表capacity,所以 Solution s = new Solution(2); s.set(1,1); //将(1,1)插入缓存,缓存是{"1"=1},set操作返回"null" s.set(2,2); //将(2,2)插入缓存,缓存是{"2"=2,"1"=1},set操作返回"null" output=s.get(1);// 因为get(1)操作,缓存更新,缓存是{"1"=1,"2"=2},get操作返回"1" s.set(3,3); //将(3,3)插入缓存,缓存容量是2,故去掉某尾的key-value,缓存是{"3"=3,"1"=1},set操作返回"null" output=s.get(2);// 因为get(2)操作,不存在对应的key,故get操作返回"-1" s.set(4,4); //将(4,4)插入缓存,缓存容量是2,故去掉某尾的key-value,缓存是{"4"=4,"3"=3},set操作返回"null" output=s.get(1);// 因为get(1)操作,不存在对应的key,故get操作返回"-1" output=s.get(3);//因为get(3)操作,缓存更新,缓存是{"3"=3,"4"=4},get操作返回"3" output=s.get(4);//因为get(4)操作,缓存更新,缓存是{"4"=4,"3"=3},get操作返回"4"

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 80ms, 内存消耗: 20780KB, 提交时间: 2022-07-05

static const auto io_sync_off = []()//lambda函数
{
    // turn off sync,关闭输入输出流的缓存
    std::ios::sync_with_stdio(false);
    // untie in/out streams,实现输入和输出流的解绑
    std::cin.tie(nullptr);
    return nullptr;
}();
class Solution {
    list<pair<int, int>> dlist;//双向链表
    unordered_map<int, list<pair<int, int>>::iterator> map;
    int cap;
    
    //用链表存,链表头部是最近使用的,尾部是最后使用的,如果要删去,就直接把尾部删去就好
public:
    Solution(int capacity){
         cap=capacity;
    }
    
    //key就变得最常用了
    int get(int key) {
        if(map.count(key))
        {
            //把这个放在头部,所以需要个tmp存着,然后删掉这个位置,再放到头部
            auto tmp=*map[key];
            dlist.erase(map[key]);
            //map.erase(key);
            dlist.push_front(tmp);//把它放在最前面
            map[key]=dlist.begin();
            //return tmp.second;
            return dlist.front().second;
        }
        return -1;
    }
    
    void set(int key, int value){
         if(map.count(key))//如果存在
         {
             dlist.erase(map[key]);//放在头部
             //map.erase(key);
         }
        else if(cap==dlist.size())
        {
            //先删掉末尾的
            auto tmp=dlist.back();
            map.erase(tmp.first);
            dlist.pop_back();
        }
        dlist.push_front(pair<int, int>(key, value));
        map[key]=dlist.begin();//第一个迭代器
    }
};

C++ 解法, 执行用时: 81ms, 内存消耗: 18480KB, 提交时间: 2022-06-19

static const auto __ = [] {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    return nullptr;
}();
class Solution {
  public:
    Solution(int capacity) {
        // write code here
        capacity_ = capacity;
    }

    int get(int key) {
        // write code here
        const auto &node = map_.find(key);
        if (node == map_.end()) {
            return -1;
        }
        cache_.splice(cache_.begin(), cache_, node->second);
        return node->second->second;
    }

    void set(int key, int value) {
        // write code here
        const auto &node = map_.find(key);
        if (node != map_.end()) {
            node->second->second = value;
            cache_.splice(cache_.begin(), cache_, node->second);
            return;
        }
        if (cache_.size() == capacity_) {
            const auto &node = cache_.back();
            map_.erase(node.first);
            cache_.pop_back();
        }
        cache_.push_front(make_pair(key, value));
        map_[key] = cache_.begin();
    }

  private:
    int capacity_;
    list<pair<int, int>> cache_;
    unordered_map<int, list<pair<int, int>>::iterator> map_;
};

C++ 解法, 执行用时: 91ms, 内存消耗: 18452KB, 提交时间: 2022-04-28

static const auto __ = [] {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    return nullptr;
}();
class Solution {
public:
    Solution(int capacity){
        capacity_ = capacity;
    }
    
    int get(int key) {
        const auto& node = map_.find(key);
        if(node == map_.end())
            return -1;
        cache_.splice(cache_.begin(), cache_, node->second);
        return node->second->second;
    }
    
    void set(int key, int value){
        const auto& node = map_.find(key);
        if(node != map_.end()){
            node->second->second = value;
            cache_.splice(cache_.begin(), cache_, node->second);
            return ;
        }
        if(cache_.size()==capacity_){
            const auto& node = cache_.back();
            map_.erase(node.first);
            cache_.pop_back();
        }
        cache_.push_front(make_pair(key, value));
        map_[key] = cache_.begin();
    }
    
private:
    int capacity_;
    list<pair<int, int>> cache_;
    unordered_map<int, list<pair<int, int>>::iterator> map_;
};

C++ 解法, 执行用时: 92ms, 内存消耗: 18448KB, 提交时间: 2022-06-17

static const auto __ = [] {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    return nullptr;
}();
class Solution {
public:
    int num_max;
    unordered_map<int, pair<int, int>> m;
    queue<int> que;
    Solution(int capacity){
         // write code here
        num_max = capacity;
    }
    
    int get(int key) {
         // write code here
        if(m.count(key)){
            que.push(key);
            m[key].second++;
            return m[key].first;
        }
        else
            return -1;
    }
    
    void set(int key, int value){
         // write code here
        que.push(key);
        if(m.count(key)){
            m[key].first = value;
            m[key].second ++;
        }
        else{
            if(num_max>0)
                num_max--;
            else{
                int tem;
                while(1){
                    tem = que.front();
                    que.pop();
                    if(m[tem].second==1){
                        m.erase(tem);
                        break;
                    }
                    m[tem].second--;
                }
            }
            m.insert(make_pair(key, pair<int, int>(value, 1)));
        }
        
    }
};

/**
 * Your Solution object will be instantiated and called as such:
 * Solution* solution = new Solution(capacity);
 * int output = solution->get(key);
 * solution->set(key,value);
 */

C++ 解法, 执行用时: 93ms, 内存消耗: 18536KB, 提交时间: 2022-06-09

static const auto __ = [] {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    return nullptr;
}();
class Solution {
  public:
    Solution(int capacity) {
        // write code here
        capacity_ = capacity;
    }

    int get(int key) {
        // write code here
        const auto& node = map_.find(key);
        if (node == map_.end()){
            return -1;
        }
        cache_.splice(cache_.begin(), cache_, node->second);
        return node->second->second;
    }

    void set(int key, int value) {
        // write code here
        const auto& node = map_.find(key);
        if (node!= map_.end()){
            node->second->second = value;
            cache_.splice(cache_.begin(), cache_, node->second);
            return;
        }
        if (cache_.size() == capacity_){
            const auto& node = cache_.back();
            map_.erase(node.first);
            cache_.pop_back();
        }
        cache_.push_front(make_pair(key, value));
        map_[key] = cache_.begin();
    }

  private:
    int capacity_;
    list<pair<int, int>> cache_;
    unordered_map<int, list<pair<int, int>>::iterator> map_;
};

/**
 * Your Solution object will be instantiated and called as such:
 * Solution* solution = new Solution(capacity);
 * int output = solution->get(key);
 * solution->set(key,value);
 */

上一题