【C++】每日一题 146 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) 的平均时间复杂度运行。

示例:

输入

"LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"

\[2\], \[1, 1\], \[2, 2\], \[1\], \[3, 3\], \[2\], \[4, 4\], \[1\], \[3\], \[4\]

输出

null, null, null, 1, null, -1, null, -1, 3, 4

解释

LRUCache lRUCache = new LRUCache(2);

lRUCache.put(1, 1); // 缓存是 {1=1}

lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}

lRUCache.get(1); // 返回 1

lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}

lRUCache.get(2); // 返回 -1 (未找到)

lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}

lRUCache.get(1); // 返回 -1 (未找到)

lRUCache.get(3); // 返回 3

lRUCache.get(4); // 返回 4

336ms

cpp 复制代码
typedef struct LRUnode{
        int key, value;
        struct LRUnode* prev;
        struct LRUnode* next;
        LRUnode():key(0),value(0),prev(NULL),next(NULL){};
        LRUnode(int key, int value):key(key),value(value),prev(NULL),next(NULL){};
}LRUnode;

class LRUCache {
private:
    unordered_map<int,LRUnode*> m;
    LRUnode *head;
    LRUnode *tail;
    int size;
    int capacity;

public:
    LRUCache(int capacity):capacity(capacity),size(0) {
        head = new LRUnode();
        tail = new LRUnode();
        head->next = tail;
        tail->prev = head;
    }
    
    int get(int key) {     
        int ret;
        auto it = m.find(key);
        if(it != m.end()){          
            ret = it->second->value;
            it->second->next->prev = it->second->prev;
            it->second->prev->next = it->second->next;
            it->second->next=head->next;
            it->second->prev = head;
            head->next->prev = it->second;
            head->next = it->second;
        }
        else{
            ret = -1;
        }
        return ret;
    }
    
    void put(int key, int value) { 
        auto it = m.find(key);
        if(it!=m.end()){
            it->second->value = value;
            it->second->next->prev = it->second->prev;
            it->second->prev->next = it->second->next;
            it->second->next=head->next;
            it->second->prev = head;
            head->next->prev = it->second;
            head->next = it->second;
        }
        else{
            LRUnode *newNode = new LRUnode(key,value);
            m.insert(make_pair(key,newNode));
            newNode->next = head->next;
            head->next->prev = newNode;
            newNode->prev = head;
            head->next = newNode;
            size++;
            if(size>capacity){
                LRUnode *delNode = tail->prev;
                //tail->prev->prev = tail;
                tail->prev = tail->prev->prev;
                tail->prev->next = tail;
                size--;
                m.erase(delNode->key);
                delete delNode;
                
                
            }
        }
    }
};
相关推荐
Fency咖啡2 分钟前
Spring进阶 - SpringMVC实现原理(二)DispatcherServlet处理请求的过程
java·后端·spring·mvc
dot to one13 分钟前
应用层:Http、Https
linux·c++·网络协议
2401_841495642 小时前
【数据结构】链栈的基本操作
java·数据结构·c++·python·算法·链表·链栈
元亓亓亓2 小时前
SSM--day2--Spring(二)--核心容器&注解开发&Spring整合
java·后端·spring
u0104058362 小时前
电商返利APP的秒杀活动架构:如何通过本地缓存(Caffeine)+ 分布式锁应对瞬时高并发?
分布式·缓存·架构
huangyuchi.2 小时前
【Linux实战 】Linux 线程池的设计、实现与单例模式应用
linux·c++·单例模式·线程池·懒汉模式·项目·linux系统
Archie_IT2 小时前
「深入浅出」嵌入式八股文—P2 内存篇
c语言·开发语言·数据结构·数据库·c++·算法
是那盏灯塔2 小时前
【算法】——动态规划算法及实践应用
数据结构·c++·算法·动态规划
程序定小飞3 小时前
基于springboot的蜗牛兼职网的设计与实现
java·数据库·vue.js·spring boot·后端·spring
Wadli3 小时前
C++面经|小林coding|(1)
开发语言·c++