146. LRU 缓存

146. LRU 缓存


题目链接:146. LRU 缓存

代码如下:

cpp 复制代码
//哈希表+双链表
//参考leetcode官方题解
//LRU:最近最少使用算法,将新插入的或刚修改或使用的放到表头,表尾即为最不常使用的
class DLinkedLNode//双链表的定义
{
public:
    int m_key,m_val;
    DLinkedLNode *pre,*next;

    DLinkedLNode():m_key(0),m_val(0),pre(nullptr),next(nullptr){}
    DLinkedLNode(int key,int value):m_key(key),m_val(value),pre(nullptr),next(nullptr){}
};

class LRUCache {
public:

    LRUCache(int capacity) {
        m_capacity=capacity;
        size=0;

        //建立头结点+尾节点
        head=new DLinkedLNode();
        tail=new DLinkedLNode();

        //首尾相连
        head->next=tail;
        tail->pre=head;
    }
    
    int get(int key) {
        if(cache.find(key)==cache.end())
            return -1;

        DLinkedLNode *node=cache[key];
        moveToHead(node);
        return node->m_val;
    }
    
    void put(int key, int value) {
        //不存在就创建
        if(cache.find(key)==cache.end())
        {
            DLinkedLNode *node=new DLinkedLNode(key,value);
            addToHead(node);
            cache[key]=node;
            size++;

            if(size>m_capacity)
            {
                cache.erase(removeTail());
                size--;
            }
        }
        else//存在就修改
        {
            DLinkedLNode* node=cache[key];
            node->m_val=value;
            moveToHead(node);
        }
    }
public:
    unordered_map<int,DLinkedLNode*> cache;
    int size;
    int m_capacity;

    DLinkedLNode *head;
    DLinkedLNode *tail;

    //把节点插入到链表头部
    void addToHead(DLinkedLNode* node)
    {
        node->pre=head;
        node->next=head->next;
        head->next->pre=node;
        head->next=node;
    }

    //把这个节点移出链表
    void removeNode(DLinkedLNode* node)
    {
        node->pre->next=node->next;
        node->next->pre=node->pre;
    }

    void moveToHead(DLinkedLNode* node)
    {
        removeNode(node);
        addToHead(node);
    }

    //返回值为key,便于查找和删除cache中保存的键值对
    int removeTail()
    {
        DLinkedLNode* node=tail->pre;
        removeNode(node);
        int key=node->m_key;
        delete node;
        return 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);
 */
相关推荐
自信150413057593 小时前
重生之从0开始学习c++之模板初级
c++·学习
历程里程碑4 小时前
2. Git版本回退全攻略:轻松掌握代码时光机
大数据·c++·git·elasticsearch·搜索引擎·github·全文检索
极客智造4 小时前
深度解析 C++ 类继承与多态:面向对象编程的核心
c++
零号全栈寒江独钓7 小时前
基于c/c++实现linux/windows跨平台获取ntp网络时间戳
linux·c语言·c++·windows
CSCN新手听安7 小时前
【linux】高级IO,以ET模式运行的epoll版本的TCP服务器实现reactor反应堆
linux·运维·服务器·c++·高级io·epoll·reactor反应堆
松☆9 小时前
C++ 算法竞赛题解:P13569 [CCPC 2024 重庆站] osu!mania —— 浮点数精度陷阱与 `eps` 的深度解析
开发语言·c++·算法
(Charon)9 小时前
【C++/Qt】C++/Qt 实现 TCP Server:支持启动监听、消息收发、日志保存
c++·qt·tcp/ip
并不喜欢吃鱼10 小时前
从零开始C++----七.继承及相关模型和底层(上篇)
开发语言·c++
tankeven11 小时前
HJ182 画展布置
c++·算法
W230357657311 小时前
【改进版】C++ 固定线程池实现:基于调用者运行的拒绝策略优化
开发语言·c++·线程池