【力扣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);
 */
相关推荐
Chenyu_3104 小时前
12.找到字符串中所有字母异位词
c语言·数据结构·算法·哈希算法
开航母的李大6 小时前
【中间件】Web服务、消息队列、缓存与微服务治理:Nginx、Kafka、Redis、Nacos 详解
前端·redis·nginx·缓存·微服务·kafka
编程绿豆侠8 小时前
力扣HOT100之栈:394. 字符串解码
java·算法·leetcode
记得早睡~9 小时前
leetcode73-矩阵置零
数据结构·leetcode·矩阵
爱coding的橙子9 小时前
每日算法刷题Day27 6.9:leetcode二分答案2道题,用时1h20min
算法·leetcode·职场和发展
GalaxyPokemon9 小时前
LeetCode - 3. 无重复字符的最长子串
算法·哈希算法·散列表
代码老y10 小时前
Redis:现代应用开发的高效内存数据存储利器
数据库·redis·缓存
zz07232011 小时前
第二十周:Redis(二)
数据库·redis·缓存
泽韦德15 小时前
【Redis】笔记|第10节|京东HotKey实现多级缓存架构
redis·笔记·缓存