146. LRU 缓存机制

146. LRU 缓存机制

题目

146. LRU 缓存机制


方法思路

  • 双向链表+hashMap
  • hashMap中保存key->node的映射关系
  • 链表结点中需要保存keyvalue前后指针
  • 需要定义虚拟头节点和尾结点,方便插入和删除
  • 将当使用一个结点时,需要将该节点加入头部,需要删除时,删除尾部的结点并且删除hashMap中的映射关系,就实现了LRU的机制

代码

// 双链表结点定义
struct Node {
    // 用来记录key,当删除双链表尾部时,可以通过key删除哈希表中对应的值
    int key;
    int value;
    Node* next;
    Node* pre;
    Node(int _value) : value(_value) {};
};

class LRUCache {
private:
    // cap记录初始的容量
    int cap;
    // size记录已经装入的键值对
    int size;
    // 哈希表,用来存储key->node的映射关系,用过哈希表的key直接定位双链表中的结点位置
    unordered_map<int, Node*> hashmap;
    // 双链表的头节点和尾结点
    Node* head;
    Node* tial;

public:
    LRUCache(int capacity) {
        // 初始cap和size
        cap = capacity;
        size = 0;
        // 使用伪头节点和伪尾结点,并且初始情况两者相连
        head = new Node(0);
        tial = new Node(0);
        head->next = tial;
        head->pre = nullptr;
        tial->pre = head;
        tial->next = nullptr;
    }

    // 将temp结点移到头位置,表示最近使用
    void moveToHead(Node* temp) {
        // 将temp结点的前后结点相连,断开temp结点
        temp->pre->next = temp->next;
        temp->next->pre = temp->pre;
        // 将temp结点插入头节点
        insertToHead(temp);
    }
    
    int get(int key) {
        // 如果在哈希表中找不到key值,返回-1,表示查找失败
        if (hashmap.find(key) == hashmap.end()) return -1;

        // 如果能找到,通过哈希表找到双链表的位置,并且返回value值
        // 将该结点移到头部,表示最近使用过
        Node* temp = hashmap[key];
        int ans = temp->value;
        moveToHead(temp);

        return ans;
    }


    // 将temp结点插入头部
    void insertToHead(Node* temp) {
        temp->next = head->next;
        temp->pre = head;
        head->next->pre = temp;
        head->next = temp;
    }
    
    // 删除尾部结点,也就是最久未使用的结点
    void deleteTial() {
        Node* temp = tial->pre;
        temp->pre->next = tial;
        tial->pre = temp->pre;
        // 防止内存泄漏
        delete temp;
    }

    void put(int key, int value) {
        // 如果put的key->value在哈希表中存在,就修改对应结点中的value值
        // 并且将该结点移动到头部,表示最近使用
        if (hashmap.find(key) != hashmap.end()) {
            Node* temp = hashmap[key];
            temp->value = value;
            moveToHead(temp);
            return;
        }
        // 如果不存在,则生成新的结点,并插入双链表头部,将key->node加入到哈希表中
        Node* temp = new Node(value);
        temp->key = key;
        insertToHead(temp);
        hashmap[key] = temp;
        // 更新size
        size++;
        // 当size超过cap值时,删除双链表中的尾结点,并且删除哈希表中对应的键值对,更新size
        if (size > cap) {
            Node* t = tial->pre;
            hashmap.erase(t->key);
            deleteTial();
            size--;
        }
    }
};

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

官方题解:146. LRU 缓存机制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值