Leetcode—146. LRU 缓存【中等】(shared_ptr、unordered_map、list)

2024每日刷题(143)

Leetcode---146. LRU 缓存

先验知识

list & unordered_map 实现代码

cpp 复制代码
struct Node{
    int key;
    int value;
    Node(int key, int value): key(key), value(value) {}
};

class LRUCache {
public:
    LRUCache(int capacity): m_capacity(capacity) {

    }
    
    int get(int key) {
        // 不存在
        const auto it = map.find(key);
        if(it == map.cend()) {
            return -1;
        }

        // 存在
        const auto& listIt = it->second;

        // 还需要更新在cache中的位置
        cache.splice(cache.begin(), cache, listIt);

        return listIt->value;
    }
    
    void put(int key, int value) {
        // 存在该元素
        if(const auto it = map.find(key); it != map.cend()) {
            const auto& listIt = it->second;
            // 需要更新map中的value
            listIt->value = value;

            // 把元素移到list前面
            cache.splice(cache.begin(), cache, listIt);
            return; 
        }

        // 不存在的情况
        // 判断cache的内存够不够
        if(cache.size() == m_capacity) {
            // 拿到cache中最后元素
            const Node& lastIt = cache.back(); 

            // erase掉map中这个元素
            map.erase(lastIt.key);

            // cache中需要pop_back()
            cache.pop_back();
        }

        // 添加新元素
        cache.emplace_front(key, value);
        map[key] = cache.begin();
    }
private:
    const int m_capacity;
    list<Node> cache;
    unordered_map<int, list<Node>::iterator> map;
};

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

运行结果

unordered_map + shared_ptr 实现代码

cpp 复制代码
struct Node{
    int key;
    int value;
    shared_ptr<Node> prev;
    shared_ptr<Node> next;
    Node(int key, int value): key(key), value(value) {}
};

class LRUCache {
public:
    LRUCache(int capacity): m_capacity(capacity) {
        join(head, tail);
    }
    
    int get(int key) {
        const auto it = map.find(key);
        // 不存在
        if(it == map.cend()) {
            return -1;
        }

        // 存在
        shared_ptr<Node> &tarNode = it->second;

        // 更新其cache位置
        remove(tarNode);
        moveToHead(tarNode);
        return tarNode->value;
    }
    
    void put(int key, int value) {
        // 存在
        if(const auto it = map.find(key); it != map.cend()) {
            shared_ptr<Node>& node = it->second;

            // 更新值
            node->value = value;

            // 更新其所在cache的位置
            remove(node);
            moveToHead(node);
            return;
        }

        // 不存在
        // 先判断cache内存是否满
        if(map.size() == m_capacity) {
            // 拿到cache中最后元素
            shared_ptr<Node> lastNode = tail->prev;

            // 并删除cache中最后元素
            remove(lastNode);

            // 删除其在map中的位置
            map.erase(lastNode->key);
        }
        // cache中添加新元素
        moveToHead(make_shared<Node>(key, value));
        map[key] = head->next;
    }

    void join(shared_ptr<Node> node1, shared_ptr<Node> node2) {
        node1->next = node2;
        node2->prev = node1;
    }

    void remove(shared_ptr<Node> node) {
        join(node->prev, node->next);
    }

    void moveToHead(shared_ptr<Node> node) {
        join(node, head->next);
        join(head, node);
    }

private:
    const int m_capacity;
    shared_ptr<Node> head = make_shared<Node>(-1, -1);
    shared_ptr<Node> tail = make_shared<Node>(-1, -1);
    unordered_map<int, shared_ptr<Node>> map;
};

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

运行结果


之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

相关推荐
sun00770015 分钟前
std::forward作用
开发语言·c++·算法
海棠玛卡1 小时前
C/C++内存管理
c++
在肯德基吃麻辣烫1 小时前
《Redis》缓存与分布式锁
redis·分布式·缓存
虾球xz1 小时前
CppCon 2018 学习:THE MOST VALUABLE VALUES
开发语言·c++·学习
2401_881244403 小时前
牛客周赛99
c++
山登绝顶我为峰 3(^v^)36 小时前
如何录制带备注的演示文稿(LaTex Beamer + Pympress)
c++·线性代数·算法·计算机·密码学·音视频·latex
先睡7 小时前
Redis的缓存击穿和缓存雪崩
redis·spring·缓存
Two_brushes.7 小时前
【算法】宽度优先遍历BFS
算法·leetcode·哈希算法·宽度优先
十五年专注C++开发8 小时前
CMake基础:条件判断详解
c++·跨平台·cmake·自动化编译
QuantumStack11 小时前
【C++ 真题】P1104 生日
开发语言·c++·算法