leetcode 之LRU Cache(26)

很实际的一道题。定义一个双向链表list,方便插入和删除;定义一个哈希表,方便查找。

具体的,哈希表存放每个结点的key和它对应的结点的地址;访问结点时,如果结点存在,则将其交换到头部,同是更新哈希表中的地址;

插入结点时,首先判断capacity是否达到了上限,如果是则在链表和哈希表中删除该结点;新结点插入链表头部。

有很多细节需要注意,双向链表和哈希表的用法,需要多加体会。

class LRUCache
{
private:
    struct CacheNode
    {
        int key;
        int value;
        CacheNode(int k, int v) :key(k), value(v){}
    };
    int capacity;
    list<CacheNode> cacheList;
    unordered_map<int, list<CacheNode>::iterator> cacheMap;
public:
    LRUCache(int capacity)
    {
        this->capacity = capacity;
    }

    int get(int key)
    {
        if (cacheMap.find(key) == cacheMap.end())return -1;
        //将当前访问的节点移到头部
        cacheList.splice(cacheList.begin(), cacheList, cacheMap[key]);
        cacheMap[key] = cacheList.begin();

        return cacheMap[key]->value;
    }

    void set(int key, int value)
    {
        //如果该结点不存在
        if (cacheMap.find(key) == cacheMap.end())
        {
            if (cacheList.size() == capacity)
            {
                //删除最少访问结点即表尾结点
                cacheMap.erase(cacheList.back().key);
                cacheList.pop_back();
            }
            //插入新结点
            cacheList.push_front(CacheNode(key, value));
            cacheMap[key] = cacheList.begin();
        }
        
        else
        {
            cacheMap[key]->value = value;
            cacheList.splice(cacheList.begin(), cacheList, cacheMap[key]);
            cacheMap[key] = cacheList.begin();
        }
    }
};
View Code

 

posted @ 2016-05-23 11:03  牧马人夏峥  阅读(151)  评论(0编辑  收藏  举报