Leetcode 146

来源:互联网 发布:七天网络手机登录入口 编辑:程序博客网 时间:2024/05/21 06:54

题意

实现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
原创粉丝点击