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

相关推荐
‘’林花谢了春红‘’3 小时前
C++ list (链表)容器
c++·链表·list
搬砖的小码农_Sky5 小时前
C语言:数组
c语言·数据结构
先鱼鲨生6 小时前
数据结构——栈、队列
数据结构
一念之坤6 小时前
零基础学Python之数据结构 -- 01篇
数据结构·python
IT 青年7 小时前
数据结构 (1)基本概念和术语
数据结构·算法
熬夜学编程的小王7 小时前
【初阶数据结构篇】双向链表的实现(赋源码)
数据结构·c++·链表·双向链表
liujjjiyun7 小时前
小R的随机播放顺序
数据结构·c++·算法
Reese_Cool9 小时前
【数据结构与算法】排序
java·c语言·开发语言·数据结构·c++·算法·排序算法
djk88889 小时前
.net将List<实体1>的数据转到List<实体2>
数据结构·list·.net
搬砖的小码农_Sky10 小时前
C语言:结构体
c语言·数据结构