码迷,mamicode.com
首页 > 系统相关 > 详细

LeetCode (26) LRU Cache

时间:2015-04-26 12:26:48      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:leetcode   算法   c++   链表   

题目描述

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.

题目要求我们实现一个缓存数据结构。要求的主要操作为获取(get)和插入(set)。需要注意的是,当缓存满了的时候,在set时需要删除最长时间没有使用的元素,并插入新元素。这就要求我们在数据结构中设计一个方法要么记录每个元素的被使用顺序,要么根据元素的被使用顺序保存元素。需要注意的是,在get元素的时候,如果元素存在于缓存中,则该元素的被使用顺序要被提前。

可以通过使用双向链表表示缓存中数据。链表的头部表示最近被使用的元素,链表的尾部表示最长时间没被使用的元素。当获取/插入元素时,将元素放置在链表的头部。需要注意的是,若插入的元素的key已经存在于缓存中,则要删除原来的数据(key, value)结点。

我们知道对链表进行随机访问的时间复杂度为O(n),那么上面的数据结构每次获得和插入元素的时间复杂度都为O(n)。为了减小时间复杂度,我们可以使用一个map结构,通过key保存结点位置,时间复杂度为O(logn)。如果要求更高的时间效率还可以使用unordered_map取代map保存结点位置。

map结构如下:

map<int, node*> cache;

根据上述思路得到的完整代码如下:

struct node
{
    int key;
    int value;
    node* pre;
    node* next;
    node(int k, int v) :key(k), value(v), pre(NULL), next(NULL) {};
};

class LRUCache{
private:
    int m_capacity;
    int m_size;
    node* m_head;
    node* m_tail;
    map<int, node*> m_cache;
public:

    LRUCache(int capacity) {
        m_capacity = capacity;
        m_size = 0;
        m_head = new node(0, 0);
        m_tail = new node(0, 0);
        m_head->next = m_tail;
        m_tail->pre = m_head;
        m_cache.clear();
    }

    ~LRUCache() {
        delete m_head;
        delete m_tail;

        map<int, node*>::iterator it;
        for (it = m_cache.begin(); it != m_cache.end(); ++it)
        {
            delete(it->second);
        }
        m_cache.clear();
    }

    void putTohead(node* cur)
    {
        cur->next = m_head->next;
        cur->next->pre = cur;
        m_head->next = cur;
        cur->pre = m_head;      
    }

    int get(int key) {
        map<int, node*>::iterator it = m_cache.find(key);
        if (it != m_cache.end())
        {
            node* cur = it->second;
            cur->pre->next = cur->next;
            cur->next->pre = cur->pre;
            putTohead(cur);
            return cur->value;
        }
        else
            return -1;
    }

    void set(int key, int value) {      
        map<int, node*>::iterator it = m_cache.find(key);
        if (it != m_cache.end())
        {
            node* cur = it->second;
            cur->value = value;
            cur->pre->next = cur->next;
            cur->next->pre = cur->pre;
            putTohead(it->second);
        }
        else 
        {
            node* new_node = new node(key, value);
            putTohead(new_node);
            m_cache[key] = new_node;
            if (m_size < m_capacity)
                m_size++;
            else
            {
                node* del = m_tail->pre;
                del->pre->next = m_tail;
                m_tail->pre = del->pre;
                it = m_cache.find(del->key);
                m_cache.erase(it);
                delete del;
            }
        }
    }
};

LeetCode (26) LRU Cache

标签:leetcode   算法   c++   链表   

原文地址:http://blog.csdn.net/angelazy/article/details/45287155

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!