LRU先进先出算法

//双链表节点
struct
dListNode{ dListNode* pre; dListNode* next; int key; int value; dListNode(int k = 0, int v = 0) :key(k), value(v), pre(NULL), next(NULL){} }; class LRUCache { public: LRUCache(int capacity):_size(capacity) { head = new dListNode(); tail = new dListNode(); head->next = tail; tail->pre = head; } void removeNode(dListNode* node) { node->pre->next = node->next; node->next->pre = node->pre; //delete node; } void aJustNodeToHead(dListNode* newNode) { //新节点头插 head->next->pre = newNode; newNode->next = head->next; head->next = newNode; newNode->pre = head; //map关联到链表 //_map.insert(make_pair(key, newNode)); } int get(int key) { auto iter = _map.find(key); if (iter != _map.end()) { //存在,先删除再头插 dListNode* node = iter->second; int targetNum = node->value; //_map.erase(key); removeNode(node); aJustNodeToHead(node); return targetNum; } return -1; } void put(int key, int value) { auto iter = _map.find(key); if (iter != _map.end()) { //存在,先删除再头插 dListNode* node = iter->second; //值变化 node->value = value; removeNode(node); aJustNodeToHead(node); } else { //不存在 if (_map.size() == _size) { //满了得先删除尾部,再头插 _map.erase(tail->pre->key); auto iter = tail->pre; removeNode(tail->pre); delete iter; } dListNode* newNode = new dListNode(key, value); aJustNodeToHead(newNode); _map.insert(make_pair(key, newNode)); } } private: dListNode* head; dListNode* tail; unordered_map<int, dListNode*> _map; int _size; };

leetcode上的题目,使用最优的时间复杂度,用hashmap保存指向双链表的指针实现查找O(1),而双链表的删除也是O(1),put和get元素都是O(1),hashmap+双链表的方法真的神,一开始自己用vector和list虽然也实现了功能,但是数据就惨很多,原因是list的查找是O(n)的,还需要定义一个指定大小的vector,着实扣脚,下边给出这个版本供参考:

class LRUCache {
public:
    LRUCache(int capacity):_size(capacity) {
        //扩容到足够大
        _vec.resize(3001);
    }

    int get(int key) {
        if(_vec[key]==0)return -1;
        int target =-1;
        for(auto iter=_list.begin();iter!=_list.end();++iter)
        {
            if(iter->first==key)
            {
                target=iter->second;
                _list.erase(iter);
                _list.push_back(make_pair(key,target));
                break;
            }
        }
        return target;
    }

    void put(int key, int value) {
         //存在先删除
        if(_vec[key]>0)
        {
            for(auto iter = _list.begin();iter!=_list.end();++iter)
            {
                if(iter->first==key)
                {
                    _list.erase(iter);
                    break;
                }
            }
        }
        if(_list.size()==_size)
        {
            //满了,说明不存在,直接删除头
            auto top=_list.front();
            --_vec[top.first];
            _list.pop_front();
        }
        _list.push_back(pair<int,int>(key,value));
        ++_vec[key];
    }
private:
    list<pair<int,int>> _list;
    //记录每个key是否存在
    vector<int> _vec;
    //链表最大长度
    int _size;
};
纯属记录程序人生,如有差错,欢迎指正,轻喷
原文地址:https://www.cnblogs.com/Cxiangyang/p/14388250.html