【力扣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);
 */
相关推荐
迪小莫学AI41 分钟前
LeetCode 1863. 找出所有子集的异或总和再求和
算法·leetcode·深度优先
一只拉古2 小时前
掌握扫描线(sweep line)算法:从LeetCode到现实应用
算法·leetcode·面试
梭七y2 小时前
【力扣hot100题】(064)在排序数组中查找元素的第一个和最后一个位置
数据结构·算法·leetcode
Dream it possible!2 小时前
LeetCode 热题 100_完全平方数(84_279_中等_C++)(动态规划(完全背包))
c++·leetcode·动态规划·完全背包
Fantasydg2 小时前
DAY 39 leetcode 18--哈希表.四数之和
算法·leetcode·散列表
luckycoding5 小时前
1631. 最小体力消耗路径
数据结构·算法·leetcode
LuckyLay5 小时前
LeetCode算法题(Go语言实现)_30
算法·leetcode·golang
Swift社区5 小时前
Swift 解 LeetCode 250:搞懂同值子树,用递归写出权限系统检查器
开发语言·leetcode·swift
爪娃侠5 小时前
LeetCode热题100记录-【矩阵、图论】
leetcode·矩阵·图论
Lenyiin5 小时前
2181、合并零之间的节点
c++·算法·leetcode·链表