【力扣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);
 */
相关推荐
黄金龙PLUS37 分钟前
SPARKLE置换算法的优缺点
算法·网络安全·密码学·哈希算法·同态加密
不会就选b37 分钟前
算法日常・每日刷题--<贪心>3
数据结构·算法·leetcode
学习星球40 分钟前
编辑距离——二维 DP 的“最小操作“艺术
c++·leetcode·java-consul
hui-梦苑1 小时前
[Gromacs]核心性能梯度测试:GROMACS 多线程性能调优实验
缓存·性能优化·多线程·gromacs·动力学模拟
wabs6662 小时前
关于二叉树【力扣107.二叉树的层序遍历II的思考】
数据结构·c++·算法·leetcode·二叉树·层序遍历
一木 之林3 小时前
四、STL 容器与数据结构(进阶)(二)
数据结构·c++·哈希算法
ysu_03143 小时前
02-单链表完全指南
c语言·数据结构·算法·leetcode
Lyyaoo.3 小时前
【链表】【中等】两数相加/倒N删除/两个交换/排序链表/LRU缓存
数据结构·链表·缓存
圣保罗的大教堂3 小时前
leetcode 3904. 最小稳定下标 II 中等
leetcode
努力努力再努力wz3 小时前
【Redis入门系列】:从 RESP 协议到 redis-plus-plus:Redis 客户端编程与 C++ 接口设计
开发语言·数据库·c++·redis·分布式·缓存·架构