leetcode系列(7)LRU Cache

来源:互联网 发布:淘宝直通车助手软件 编辑:程序博客网 时间:2024/04/30 19:06

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.

set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

关于LRU Cache(Least Recently Used Cache)的介绍其实题目的描述就非常清楚了,

这里(http://www.cs.uml.edu/~jlu1/doc/codes/lruCache.html)和这里(http://hawstein.com/posts/lru-cache-impl.html)也介绍了而且都给出了实现。其实实现机制非常简单就是一个哈希+链表,可以明确get和set的行为之后代码就很容易写出来(think before coding):

get(key) 实际是从哈希表中根据key查找该节点是否存在并返回其指针,链表中是实际的节点,如果key在哈希表中能够查找到则返回其value,并将该节点移到链表头(LRU特性),如果不存在则直接返回-1。

set(key,vlaue) 首先查找哈希表是否存在该key,如果存在则直接修改其指向的节点的value之后移动该节点到链表头,如果不存在则构造一个新的节点在哈希中添加该key,并该节点插入表头,不要忘记做一个判断就是是否超出了容量,如果超出容量则需要删除链表的最后一个节点,并将该key从哈希表中移除。

代码如下:

class LRUCache{public:    LRUCache(int capacity) : _cap(capacity), _num(0)    {        _head = new Node();        _tail = new Node();        _head->next = _tail;        _tail->pre = _head;    }    int get(int key) {        int ret = -1;        if (is_find(key)) {            Node* ptr = _hash.at(key);            ret = ptr->value;            move_to_head(ptr);        }        return ret;    }    void set(int key, int value) {         if (is_find(key)) {            Node* ptr = _hash.at(key);            ptr->value = value;            move_to_head(ptr);        } else {            Node* ptr = new Node(key,value);            _hash[key] = ptr;            ++_num;            insert_to_head(ptr);            if (is_full()) {                --_num;                ptr = _tail->pre;                _hash.erase(ptr->key);                remove_last_node(ptr);                            }        }    }private:    struct Node {        int key;        int value;        Node* pre;        Node* next;        Node() : key(-1), value(-1), pre(NULL), next(NULL)         {        }        Node(int k, int v) : key(k), value(v), pre(NULL), next(NULL)         {        }    };    Node* _head;    Node* _tail;    map<int, Node*> _hash;    int _num;    int _cap;    bool is_full() {        return _num > _cap;    }    bool is_find(int k) {        return (_hash.end() != _hash.find(k));    }    void insert_to_head(Node* ptr) {        ptr->pre = _head;        ptr->next = _head->next;        _head->next->pre = ptr;        _head->next = ptr;    }    void move_to_head(Node* ptr) {        ptr->next->pre = ptr->pre;        ptr->pre->next = ptr->next;        insert_to_head(ptr);    }    void remove_last_node(Node* ptr) {        ptr->pre->next = _tail;        _tail->pre = ptr->pre;        delete ptr;    }};


其实实现一个工业级的LRU Cache就得重新考虑很多问题了,起码不能直接使用STL的map了,在levelDB中非常精彩的实现了一个工业级的LRU Cache,等有空的时候再写一篇博客介绍下。


0 0
原创粉丝点击