链表: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的调用次数

相关推荐
yuannl1030 分钟前
数据结构----二叉排序树(ai修改版)
数据结构
iiiiyu1 小时前
集合进阶(Map集合)
java·大数据·开发语言·数据结构·编程语言
小江的记录本1 小时前
【Java基础】核心关键字:final、static、volatile、synchronized、transient(附《思维导图》+《面试高频考点清单》)
java·前端·数据结构·后端·ai·面试·ai编程
go不是csgo2 小时前
两个Redis数据结构搞定签到和UV统计:Bitmap与HyperLogLog实战
数据结构·redis·uv
悠仁さん3 小时前
数据结构 栈与队
数据结构
Plan-C-3 小时前
二叉树的遍历
java·数据结构·算法
历程里程碑3 小时前
54 深入解析poll多路复用技术
java·linux·服务器·开发语言·前端·数据结构·c++
一切皆是因缘际会4 小时前
AI Agent落地困局与突破:从技术架构到企业解析
数据结构·人工智能·算法·架构
qeen874 小时前
【算法笔记】各种常见排序算法详细解析(下)
c语言·数据结构·c++·笔记·学习·算法·排序算法
欢璃4 小时前
笔试强训练习
java·开发语言·jvm·数据结构·算法·贪心算法·动态规划