力扣HOT100之链表:146. LRU 缓存

这道题从来没做过,完全不知道该怎么写,直接去看视频了,感觉这个视频讲解的挺好的。

这道题主要是需要自己额外定义数据结构和函数,需要定义节点结构体,用于存放键值对,每个节点都有前后指针,所以这道题是采用哈希表+双向链表的做法来做的。这道题添加和删除节点的逻辑都很好理解,最难想到的就是当插入节点,但缓存已满时,如何找到最久未使用的节点,这个实现起来不难,每一次插入节点都从头部插入,不常使用的节点总是在链表的最末端,所以我们只需要将末端的节点删除即可。

cpp 复制代码
//定义节点
struct Node{
    int key, val;
    Node *pre, *next;
    Node() : key(0), val(0), pre(nullptr), next(nullptr){}
    Node(int _key, int _val) : key(_key), val(_val), pre(nullptr), next(nullptr){}
};

class LRUCache {
public:
    Node *head, *tail;   //双向链表的头节点和尾节点
    unordered_map<int, Node*> hash;    //内部维护一个哈希表
    int capacity, size;   //容量和当前元素个数
    LRUCache(int _capacity) {
        capacity = _capacity;
        size = 0;
        head = new Node();
        tail = new Node();
        head -> next = tail;
        tail -> pre = head;
    }
    
    int get(int key) {
        if(!hash.count(key))
            return -1;
        Node* node = hash[key];
        removeNode(node);
        addNodeHead(node);
        return node -> val;
    }
    
    void put(int key, int value) {
        if(hash.count(key)){   //该键已经存在
            Node* node = hash[key];
            node -> val = value;
            removeNode(node);
            addNodeHead(node);
        }
        else{   //插入的为新键
            if(size >= capacity){  //已经达到最大容量
                Node* removed = tail -> pre;  //删除双向链表中的最后一个节点
                hash.erase(removed -> key);  //及时从哈希表中删除不活跃节点对应的键
                removeNode(removed);
                size--;
            }
            Node *node = new Node(key, value);
            addNodeHead(node);
            hash[key] = node;
            size++;
        }
    }
    //自定义删除节点函数
    void removeNode(Node *node){
        node -> pre -> next = node -> next;
        node -> next -> pre = node -> pre;
    }
    //自定义添加节点函数
    void addNodeHead(Node *node){
        node -> pre = head;
        node -> next = head -> next;
        head -> next -> pre = node;
        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);
 */
相关推荐
weixin1997010801639 分钟前
《1688图片空间API踩坑:img.upload 与 album.* 的防盗链与CDN缓存问题》(附Python源码)
开发语言·python·缓存
夏幻灵1 小时前
每日一题:LeetCode 206:反转链表——三指针与原地反转详解
算法·leetcode·链表
hweiyu001 小时前
Redis命令:BLPOP
redis·缓存
Tisfy4 小时前
LeetCode 0301.删除无效的括号:二进制枚举 / 回溯
算法·leetcode·字符串·题解·回溯·括号匹配·二进制枚举
Nil2085 小时前
leetcode 322零钱兑换
算法·leetcode·职场和发展
yi0115 小时前
DAY24: LeetCode 167:两数之和 II|从暴力枚举到左右双指针
笔记·python·算法·leetcode·二分查找·双指针
木井巳5 小时前
【BFS 解决拓扑排序】课程表
java·算法·leetcode·广度优先·宽度优先·推荐算法·图搜索算法
yi0115 小时前
LeetCode 15:三数之和|排序 + 双指针,如何避免重复答案?
笔记·python·算法·leetcode·双指针
alphaTao6 小时前
LeetCode 每日一题 2026/10/5-2026/10/11
算法·leetcode
小小龙学IT7 小时前
C++ Redis 客户端深度解析(hiredis 与 redis-plus-plus)——工业数采实时缓存 C++ 侧实战
c++·redis·缓存