【力扣hot100题】(034)LRU缓存

做完这题已经没有任何力气写链表题了。

思路很简单,就是调试特别的痛苦。

老是频频报错,唉。

cpp 复制代码
class LRUCache {
public:
    struct ListNode{
        int key,val;
        ListNode* next; 
        ListNode* prev;
        ListNode() : key(0), val(0), next(nullptr), prev(nullptr) {}
        ListNode(int key, int value) : key(key), val(value), next(nullptr), prev(nullptr) {}
        ListNode(int key, int value, ListNode* next=nullptr, ListNode* prev=nullptr) : key(key), val(value), next(next), prev(prev) {}
    };
    ListNode* head=new ListNode();
    ListNode* tail=head;
    int capacity;
    map<int,ListNode*> hash;
    LRUCache(int capacity) {
        this->capacity=capacity;
    }
    
    int get(int key) {
        if(hash.find(key)!=hash.end()){
            if(head->next==hash[key]) return hash[key]->val;
            hash[key]->prev->next=hash[key]->next;
            if(hash[key]->next) hash[key]->next->prev=hash[key]->prev;
            if(hash[key]==tail) tail=hash[key]->prev;
            hash[key]->next=head->next;
            if(head->next) head->next->prev=hash[key];
            hash[key]->prev=head;
            head->next=hash[key];
            return hash[key]->val;
        }
        else return -1;
    }
    
    void put(int key, int value) {
        if(hash.find(key)!=hash.end()){
            hash[key]->val=value;
            get(key);
            return;
        }
        else if(capacity==0){
            hash.erase(tail->key);
            tail=tail->prev;
            tail->next=nullptr;
        }
        else capacity--;
        ListNode* newhead=new ListNode(key,value,head->next,head);
        if(tail==head) tail=newhead;
        if(head->next) head->next->prev=newhead;
        head->next=newhead;
        hash[key]=newhead;
    }
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */

看了答案,其实有更好的做法,可以优化并且降低代码的复杂度,感觉我写代码还是太畏缩了。

优化方案一:将头指针和尾指针都设成虚拟指针,一个指向双向链表头部的前一个位置,一个指向尾部的后一个位置。(我写的时候为了节省空间复杂度只弄了一个头虚拟指针,还是太不敢了)

优化方案二:构造更多的函数,这样就可以直接调用,代码逻辑会清晰很多。

于是按这个改进思路又写了一遍,果然简单多了......

cpp 复制代码
class LRUCache {
public:
    struct ListNode{
        int key,val;
        ListNode* next; 
        ListNode* prev;
        ListNode() : key(0), val(0), next(nullptr), prev(nullptr) {}
        ListNode(int key, int value, ListNode* next=nullptr, ListNode* prev=nullptr) : key(key), val(value), next(next), prev(prev) {}
    };
    ListNode* head;
    ListNode* tail;
    int capacity;
    unordered_map<int,ListNode*> hash;
    LRUCache(int capacity) {
        this->capacity=capacity;
        head=new ListNode();
        tail=new ListNode(0,0,nullptr,head);
        head->next=tail;
    }
    
    int get(int key) {
        if(hash.find(key)==hash.end()) return -1;
        erase(hash[key]);
        insert(hash[key]);
        return hash[key]->val;
    }
    
    void put(int key, int value) {
        if(hash.find(key)!=hash.end()){
            hash[key]->val=value;
            erase(hash[key]);
            insert(hash[key]);
            return ;
        }
        if(capacity>0) capacity--;
        else if(capacity==0){
            hash.erase(tail->prev->key);
            erase(tail->prev);
        }
        ListNode* newnode=new ListNode(key,value,nullptr,nullptr);
        insert(newnode);
        hash[key]=newnode;
    }

    void erase(ListNode* node){
        node->prev->next=node->next;
        node->next->prev=node->prev;
    }
    void insert(ListNode* node){
        head->next->prev=node;
        node->next=head->next;
        node->prev=head;
        head->next=node;
    }
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */
相关推荐
thusloop1 小时前
380. O(1) 时间插入、删除和获取随机元素
数据结构·算法·leetcode
緈福的街口2 小时前
【leetcode】584. 寻找用户推荐人
算法·leetcode·职场和发展
Maybyy3 小时前
力扣242.有效的字母异位词
java·javascript·leetcode
wjcurry3 小时前
完全和零一背包
数据结构·算法·leetcode
xinghunzhiye20104 小时前
redis升级
数据库·redis·缓存
sqyaa.5 小时前
Guava LoadingCache
jvm·缓存·guava
Hello.Reader8 小时前
RedisJSON 内存占用剖析与调优
数据库·redis·缓存
科大饭桶9 小时前
数据结构自学Day5--链表知识总结
数据结构·算法·leetcode·链表·c
jndingxin10 小时前
OpenCV 图像哈希类cv::img_hash::AverageHash
人工智能·opencv·哈希算法
YuTaoShao11 小时前
【LeetCode 热题 100】24. 两两交换链表中的节点——(解法一)迭代+哨兵
java·算法·leetcode·链表