• 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;
    };
    纯属记录程序人生,如有差错,欢迎指正,轻喷
  • 相关阅读:
    thinkphp5整合 gatewaywork实现聊天
    php输出日志
    php的ob函数实现页面静态化
    30个php操作redis常用方法代码例子
    redis三种启动方式
    Redis实战
    支付宝即时到账接口开发
    PHP生成excel表格文件并下载
    微信平台提供三种公众号
    【Performance】chrome调试面板
  • 原文地址:https://www.cnblogs.com/Cxiangyang/p/14388250.html
Copyright © 2020-2023  润新知