LeetCode 146. LRU 缓存

本文介绍了如何使用双向链表配合哈希表实现LRU缓存,当缓存容量超过限制时,自动移除最久未使用的元素。通过get和put操作调整链表结构以保持最近使用状态。
摘要由CSDN通过智能技术生成

146. LRU 缓存

 存和取都需要O(1),原本可以用哈希表实现,但是题目还有个条件,在容量超过capacity的时候删掉最久不用的元素,因此增加一个双向链表,在数据被get和put的时候均将对应的元素移动到表尾。这样越靠近表尾越近被使用过,每次需要删除最久未使用的就删掉表头的元素即可。

struct DListNode {
    int data;
    int key;
    DListNode* next=nullptr;
    DListNode* pred = nullptr;
};

class LRUCache {
public:
    unordered_map<int ,DListNode*> umap;
    DListNode* head = nullptr;
    DListNode* tail = nullptr;
    int cap;

    LRUCache(int capacity) {
        cap = capacity;
        head = new DListNode();
        tail = new DListNode();// 设置头节点和尾节点
        head -> next = tail;
        tail -> pred = head;
    }
    
    int get(int key) {
        if (umap.find(key) == umap.end()){
            return -1;
        }
        else {
            DListNode* current = umap[key];
            // 访问了,元素挪到链表最后
            current -> pred -> next = current -> next;
            current -> next -> pred = current -> pred;
            current -> next = tail;
            current -> pred = tail -> pred;
            tail -> pred -> next = current;
            tail -> pred = current;
            return current ->data;
        }
        
    }
    
    void put(int key, int value) {
        // 修改的元素和新加入的元素都加到链表最后。
        if (umap.find(key) != umap.end()) {
            umap[key] -> data = value;
            DListNode* current = umap[key];
            current -> pred -> next = current -> next;
            current -> next -> pred = current -> pred;
            current -> next = tail;
            current -> pred = tail -> pred;
            tail -> pred -> next = current;
            tail -> pred = current;
        }
        else {
            DListNode* new_node = new DListNode();
            new_node -> data = value;
            new_node -> key = key;
            umap[key] = new_node;
            new_node -> next = tail;
            new_node -> pred = tail -> pred;
            tail -> pred -> next = new_node;
            tail -> pred = new_node;
            if (umap.size() > cap) {
                DListNode* deleteNode = head -> next;
                head -> next = deleteNode -> next;
                deleteNode -> next -> pred = head;
                
                umap.erase(deleteNode->key);
                delete deleteNode;
                
            }
           

        }
    }
};

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

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值