链表:LRU缓存

LeetCode146 LRU缓存

cpp 复制代码
class Node{
public:
    int key;
    int value;
    Node* pre;
    Node* next;
    Node(int k=0,int v=0):key(k),value(v){}
};

class LRUCache {
private:
    int capacity;
    Node* dummy; //哨兵节点
    unordered_map<int,Node*> key_node;

    //删除一个节点(抽出一本书)
    void remove(Node* x){
        x->next->pre=x->pre;
        x->pre->next=x->next;
    }

    //在链表头添加一个节点(把一本书放在最上面)
    void push_front(Node* x){
        x->pre=dummy;
        x->next=dummy->next;
        dummy->next=x;
        x->next->pre=x;    
    }

    //获取key对应的节点, 同时把节点移到链表头部
    Node* get_node(int key){
        auto it=key_node.find(key);
        if(it==key_node.end()){//没有这个关键值(这本书)
            return nullptr;
        }
        Node* node=it->second;
        remove(node); //将这本书抽出来
        push_front(node); //放在最上面
        return node;
    }

public:
    LRUCache(int capacity):capacity(capacity),dummy(new Node()) {
        dummy->next=dummy;
        dummy->pre=dummy;
    }
    
    int get(int key) { //如果关键字key存在于缓存中,则返回关键字的值,否则返回-1
        Node* node=get_node(key);
        if(node==nullptr) return -1;
        return node->value;
    }
    
    void put(int key, int value)
        Node* node=get_node(key);
        if(node!=nullptr){//关键字key已存在,变更其数据值value
            node->value=value;
            return;
        }
        else{ //如果不存在,则向缓存中插入该组 key-value。如果插入操作导致关键字数量超过 capacity ,则应该逐出最久未使用的关键字。
            Node* new_node=new Node(key,value); //新书
            key_node[key]=new_node;
            push_front(new_node); //放在最上面 
            if(key_node.size()>capacity){ //书太多了
                Node* back_node=dummy->pre; //找到最后一本书
                key_node.erase(back_node->key);
                remove(dummy->pre); //去掉最后一本书
                delete back_node; //释放内存
            }
        }
    }
};

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

时间复杂度:所有操作的时间复杂度均为O(1)

空间复杂度:O(min(p, capacity)),p为put的调用次数

相关推荐
胖咕噜的稞达鸭2 小时前
C++中的父继子承:继承方式实现栈及同名隐藏和函数重载的本质区别, 派生类的4个默认成员函数
java·c语言·开发语言·数据结构·c++·redis·算法
笑口常开xpr2 小时前
【C++】模板 - - - 泛型编程的魔法模具,一键生成各类代码
开发语言·数据结构·c++·算法
立志成为大牛的小牛2 小时前
数据结构——十四、构造二叉树(王道408)
数据结构·笔记·学习·程序人生·考研
笑口常开xpr3 小时前
【C++继承】深入浅出C++继承机制
开发语言·数据结构·c++·算法
HQChart3 小时前
HQChart使用教程30-K线图如何对接第3方数据46-DRAWTEXT_FIX数据结构
数据结构·hqchart·k线图
七饭4 小时前
C语言数据结构-排序
c语言·数据结构·排序算法
_dindong7 小时前
基础算法:滑动窗口
数据结构·学习·算法·leetcode·力扣
Voyager_47 小时前
图像处理踩坑:浮点数误差导致的缩放尺寸异常与解决办法
数据结构·图像处理·人工智能·python·算法
信奥卷王11 小时前
[GESP202503 五级] 原根判断
java·数据结构·算法
haoly198915 小时前
数据结构和算法篇-线性查找优化-移至开头策略
数据结构·算法·移至开头策略