欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > LeetCode146. LRU 缓存(2024秋季每日一题 37)

LeetCode146. LRU 缓存(2024秋季每日一题 37)

2024/10/23 23:33:44 来源:https://blog.csdn.net/qq_46456049/article/details/142948406  浏览:    关键词:LeetCode146. LRU 缓存(2024秋季每日一题 37)

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:

  • LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
  • void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。

函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

示例:

输入

[“LRUCache”, “put”, “put”, “get”, “put”, “get”, “put”, “get”, “get”, “get”]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]

解释

LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4

提示:

1 < = c a p a c i t y < = 3000 1 <= capacity <= 3000 1<=capacity<=3000
0 < = k e y < = 10000 0 <= key <= 10000 0<=key<=10000
0 < = v a l u e < = 1 0 5 0 <= value <= 10^5 0<=value<=105
最多调用 2 ∗ 1 0 5 2 * 10^5 2105getput


思路:双链表 + 哈希表
时间复杂度:get: O ( 1 ) O(1) O(1)、put: O ( 1 ) O(1) O(1)

  • 初始化缓存时,创建 head,tail 节点,并且相互指向彼此,初始化容器容量、容器节点数量
  • get 时:
    • 如果当前 key 存在,则将当前 key 对应的节点移到链表头部(通过 map 保存),并返回 节点的 val 值
    • 如果当前 key 不存在,则直接返回 -1
  • put 时:
    • 如果当前 key 存在,则通过 hash 表 找到对应的节点,将此节点挪到链表头部,并更新节点的 val 值
    • 如果当前 key 不存在
      • 如果链表中 当前节点数量 < 容量,则新建节点,将节点添加到链表 头部
      • 如果链表中 当前节点数量 >= 容量,则删除尾部节点,新建节点,将节点添加到 链表头部
      • 更新链表中节点 cnt 数量

map:unordered_map<int, Node *> mp;

struct Node{Node * pre, * ne;int key, val;Node(){pre = nullptr;ne = nullptr;key = 0;val = 0;}Node(int _key, int _val){key = _key, val = _val;pre = ne = nullptr;}
};
class LRUCache {
private:Node * head;Node * tail;unordered_map<int, Node *> mp;int cnt;int n;
public:LRUCache(int capacity) {cnt = 0;n = capacity;head = new Node();tail = new Node();head -> ne = tail;tail -> pre = head;}int get(int key) {if(!mp.count(key)){return -1;}Node * cur = mp[key];moveToHead(cur);return cur -> val;}void put(int key, int value) {if(!mp.count(key)){cnt++;Node * cur = new Node(key, value);if(cnt > n){removeTail();addToHead(cur);cnt = n;}else{addToHead(cur);}//mp[key]= cur;mp.insert({key, cur});}else{Node * cur = mp[key];cur -> val = value;moveToHead(cur);}}void removeTail(){mp.erase(tail -> pre -> key);tail -> pre = tail ->pre -> pre;tail -> pre -> ne = tail;}void addToHead(Node * cur){cur -> pre = head;cur -> ne = head -> ne;head -> ne -> pre = cur;head -> ne = cur;}void moveToHead(Node * cur){cur -> ne -> pre = cur -> pre;cur -> pre -> ne = cur -> ne;addToHead(cur);}
};

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com