Leetcode 146 - LRU Cache(HashMap + List)

8 篇文章 0 订阅
8 篇文章 0 订阅

题意

实现LRU缓存(Least Recently Used)。
要求:所有操作都是 O(1) 的。
LRU缓存机制:假设我们能够缓存的数目为n。在加入新元素时:当容量小于n时,我们直接加入新元素;若容量已经达到n,我们置换出最久没有使用的那个元素,并且加入我们的新元素。

思路

HashMap + list。
我们需要支持的操作是put(int key, int value)get(int key)操作。
我们如下定义我们的数据结构:

struct cacheNode {
    int key, value;
};

unordered_map<int, list<cacheNode*>::iterator> f;
list<cacheNode*> cache;

首先,我们用一个双向链表cache来保存我们的节点。其中,节点的头部保存的是最近使用的,节点的尾部保存的是最久没使用的。从节点头部到尾部使用的时间越来越远。
f建立了我们key和节点的映射。
当我们get(key)的时候:我们先去f里面 O(1) 的查找对应节点在list中的位置,然后返回那个节点对应的value即可。并且,需要将这个节点放到链表的头部,并且重新建立映射。直接利用链表删除和增加节点 O(1) 的去操作即可。
当我们put(key, value)的时候:
1. 查找该key值是否存在,如果存在,我们需要删除原来的节点,将其新的value更新后插入到链表的头部,重新建立映射。
2. 如果该key不存在,首先如果容量已经达到n,我们从链表尾删除最后一个元素,并且将新节点加入到链表头部,建立映射。

代码

struct cacheNode {
    int key;
    int val;
    cacheNode() {}
    cacheNode(int x, int y) : key(x), val(y) {}
};

class LRUCache {
private:
    int n;
    list<cacheNode*> cache;
    unordered_map<int, list<cacheNode*>::iterator> f;

public:
    LRUCache(int capacity) {
        n = capacity;
    }

    void moveToFront(int key) {
        auto it = f[key];
        int value = (*it)->val;
        cache.erase(it);
        cache.push_front(new cacheNode{key, value});
        f[key] = cache.begin();
    }

    int get(int key) {
        if (f.find(key) == f.end()) return -1;
        moveToFront(key);
        return (*f[key])->val;
    }

    void put(int key, int value) {
        if (f.find(key) == f.end()) {
            while (cache.size() >= n) {
                int newKey = (cache.back())->key;
                cache.pop_back();
                auto it = f.find(newKey);
                f.erase(it);
            }
            cache.push_front(new cacheNode{key, value});
            f[key] = cache.begin();    
        } else {
            auto it = f[key];
            cache.erase(it);
            cache.push_front(new cacheNode{key, value});
            f[key] = cache.begin();
        }
    }
};

/**
 * 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);
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值