C++实现LRU Cache

 1、算法思路:

put操作思路:

用一个双向链表和一个哈希表;

每添加一个(key, value),先判断是否在哈希表中存在,如果存在,那么删除哈希表中的键值对和双向链表中的该元素;

再往双向链表头部增加添加的(key, value)和哈希表中增加(key,value);

最后判断是否超过capacity,若超过则弹出链表尾部元素和删除哈希表中该键值对。

优化:

哈希表中保存<int, list<in, int>::iterator>,这样可以再O(1)时间找到双向链表key对应的节点。

2、list和unordered_map常用方法:

unordered_map<int, int>mp;

mp.erase(key):通过key删除元素

mp.size():mp元素个数

list.size():元素个数

list.front():第一个元素

list.back():最后一个元素

list.push_front():增加一个元素到链表头部

list.pop_front()

list.push_back()

lis.pop_back():删除最末元素

list.erase(it):it为迭代器

注意:list没有find函数

3、代码: 

#pragma once
#include<list>
#include<unordered_map>
using namespace std;

class LRUCache
{
public:
    LRUCache();
    ~LRUCache();
    LRUCache(int capacity) {
        this->capacity = capacity;
    }

    int get(int key) {

        if (mp.find(key) != mp.end())
        {
            put(key, mp[key]->second);
            return mp[key]->second;
        }
        else
        {
            return -1;
        }
    }

    void put(int key, int value) {

        if (mp.find(key) != mp.end()) //说明原来中有键key,删除双向链表中的key-val
        {
            list1.erase(mp[key]);
            //for (auto it = list1.begin(); it != list1.end(); it++)
            //{
            //    if ((*it).first == key)
            //    {
            //        list1.erase(it);
            //        break;
            //    }
            //}
        }
        list1.push_front(make_pair(key, value)); //添加元素到链表头
        mp[key] = list1.begin();//注意

        if(list1.size() > capacity)
        {
            mp.erase(list1.back().first);
            list1.pop_back();
        }

    }

private:
    int capacity;
    list<pair<int, int>>list1;
    unordered_map<int, list<pair<int, int>>::iterator>mp; //注意

};

猜你喜欢

转载自blog.csdn.net/qq_33457548/article/details/98211715