《每日一题》——146. LRU 缓存|460. LFU 缓存
class LRUCache {
public:
//函数 get 和 put 必须以 O(1) 的平均时间复杂度运行
//保持把新鲜数据往链表头移动。新鲜的定义:刚被修改(put),或者访问过(get),就算新鲜,就需要放到链表头。
//过期键直接 pop_back(),链表节点越往后,越陈旧struct Node{int key, value;Node* left,* right;Node(){};Node(int k, int v):key(k), value(v), left(nullptr), right(nullptr){};};int n;unordered_map<int, Node*> mp; Node* L, *R;//利用虚拟的头节点和尾节点来帮助删除和插入LRUCache(int capacity) {n = capacity;L = new Node(-1, -1);R = new Node(-1, -1);L->right = R;R->left = L;}//p->left p p->rightvoid remove(Node* p){//删除p节点p->right->left = p->left;p->left->right = p->right;}//L p L->rightvoid insert(Node* p){//将p节点移动到虚拟头节点后面p->right = L->right;p->left = L;L->right->left = p;L->right = p;}int get(int key) {if (!mp.count(key)){return -1;}int v = mp[key]->value;remove(mp[key]);insert(mp[key]);return v;}void put(int key, int value) {if (mp.count(key)){mp[key]->value = value;remove(mp[key]);insert(mp[key]);}else{if (mp.size() == n){Node* p = R->left;remove(p);mp.erase(p->key);delete p;}//否则,插入(key, value)Node* p = new Node(key,value);mp[key] = p;insert(p);}}
};/*** 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);*/
struct Node{int key;int val;int freq;//频率Node* left;Node* right;Node(): key(-1), val(-1), freq(0), left(nullptr), right(nullptr){}Node(int _k, int _v): key(_k), val(_v), freq(1), left(nullptr), right(nullptr){}
};struct FreqList{int freq;Node* vhead;Node* vtail;FreqList (int _f): freq(_f), vhead(new Node()), vtail(new Node()){vhead->right = vtail;vtail->left = vhead;}
};//虚构的头、尾节点
class LFUCache {
private:unordered_map<int, Node*> mp;//unordered_map<int, FreqList*> freq_map;//频率节点int n;int min_freq;
public:LFUCache(int capacity): n(capacity) {}//p->left p p->rightvoid remove(Node* p){//操作和LRU类似p->right->left = p->left;p->left->right = p->right;}void inserthead(Node* p){//放到同频率的对头int freq = p->freq;if (freq_map.find(freq) == freq_map.end()){//没找到这个频率的freq_map[freq] = new FreqList(freq);}//L p L->right//操作和LRU类似FreqList* L = freq_map[freq];p->right = L->vhead->right;p->left = L->vhead;L->vhead->right->left = p;L->vhead->right = p;}bool empty(FreqList* L){return L->vhead->right == L->vtail ? true: false;}int get(int key) {int res = -1;if (mp.find(key) != mp.end()){//找到了Node* p = mp[key];res = p->val;remove(p);p->freq++;if (empty(freq_map[min_freq])) min_freq++;//生成一个频率的双向链表inserthead(p);}return res;}void put(int key, int value) {if (n == 0) return;if (get(key) != -1){mp[key]->val = value;}else{if (mp.size() == n){//满了Node* p = freq_map[min_freq]->vtail->left;remove(p);mp.erase(p->key);delete p;}Node* p = new Node(key, value);mp[key] = p;min_freq = 1;//新加入的频率最低为1inserthead(p);}}
};/*** Your LFUCache object will be instantiated and called as such:* LFUCache* obj = new LFUCache(capacity);* int param_1 = obj->get(key);* obj->put(key,value);*/
《每日一题》——146. LRU 缓存|460. LFU 缓存相关推荐
- lfu算法c语言,LeetCode算法系列 460. LFU 缓存机制
力扣原题 460. LFU 缓存机制 请你为 最不经常使用(LFU)缓存算法设计并实现数据结构. 实现 LFUCache 类:LFUCache(int capacity) - 用数据结构的容量 cap ...
- 460. LFU 缓存
460. LFU 缓存 请你为 最不经常使用(LFU)缓存算法设计并实现数据结构. 实现 LFUCache 类: LFUCache(int capacity) - 用数据结构的容量 capacity ...
- leetcode 460. LFU 缓存 hard
leetcode 460. LFU 缓存 hard 题目描述: 请你为 最不经常使用(LFU)缓存算法设计并实现数据结构. 实现 LFUCache 类: LFUCache(int capacity) ...
- 学习笔记 | LeetCode 460. LFU缓存
LeetCode 460. LFU缓存 请你为 最不经常使用(LFU)缓存算法设计并实现数据结构.它应该支持以下操作:get 和 put. get(key)- 如果键存在于缓存中,则获取键的值(总是正 ...
- LeetCode 460. LFU缓存(哈希双链表)
1. 题目 设计并实现最不经常使用(LFU)缓存的数据结构.它应该支持以下操作:get 和 put. get(key) - 如果键存在于缓存中,则获取键的值(总是正数),否则返回 -1. put(ke ...
- LeetCode 460. LFU 缓存 -- 哈希查询+双向链表
LFU 缓存 困难 634 相关企业 请你为 最不经常使用(LFU)缓存算法设计并实现数据结构. 实现 LFUCache 类: LFUCache(int capacity) - 用数据结构的容量 ca ...
- LeetCode 460. LFU缓存
文章目录 题目描述 思路 实现 解法二 扩展 题目描述 实现一个LFU缓存(Least Frequently Used). 在需要移除元素时,移除最近访问频率最低的.可以对每个元素增加一个计数器,访问 ...
- 力扣 460. LFU 缓存
题目来源:https://leetcode.cn/problems/lfu-cache/ 大致题意: 设计一个 LFU 缓存类: LFUCache(int capacity) - 用数据结构的容量 c ...
- lfu实现 java_LFU算法实现(460. LFU缓存)
今天字节客户端三面问了这道题,没做出来.第一,之前没见过lfu,第二,要求O(1)时间,条件苛刻一点.只能说无缘字节. 言归正传,LFU算法:least frequently used,最近最不经常使 ...
最新文章
- Linux C编程--网络编程1--字节顺序和字节处理函数
- 温故(2):pass by value
- FLEX实例:GOOGLE地图.
- 【CI/CD1】jenkins
- SQL服务器引擎组件概览
- torch.nn模块介绍
- 第009讲 初识css 类选择器 id选择器 html选择器
- 微信小程序底部突起半圆设计
- matlab的mkdir创建新的文件夹,并把图像保存在该文件夹内
- android 代码混淆原理,Android 代码混淆
- 小波变换matlab代码,matlab小波变换代码
- 2020.12.28Excel(数字到BZZ)
- c语言苹果大小分级,苹果品质分级标准您知道吗?
- 刨根究底字符编码之八——Unicode编码方案概述
- matlab的containers.Map类型介绍
- 苹果ipad找不到服务器怎么办,找不到网络怎么办 ipad无法加入无线网络解决方法【详解】...
- 人力资源管理中的能力素质模型
- $STRM 空投和 Strategy Stakers 代币分配
- Python程序员面向对象技巧梳理
- python枚举算法流程图_算法-枚举
热门文章
- 阿里巴巴年度技术总结 - 人工智能在搜索的应用和实践
- Echo,Linux上最忧伤的命令(故事)
- 阿里云创建AccessKey 和 Access Key Secert
- Web防火墙(WAF)是什么?和传统防火墙区别是什么?
- SqlServer 如何插入图片和导出图片数据
- JS-变量提升与暂时性死区概念
- 当我们想要用LinkedIn领英开发客户时,如何设计填写职位头衔?
- Atitit 手机号码选号 规范 流程 attilax总结 v2 r99.docx
- python在医学中的应用_如何应用Python处理医学影像学中的DICOM信息
- C语言中p, *p, p, *p, **p的理解-初级