[解题报告]LFU Cache

题目链接
题目要求使用O(1)的Get、Put方法实现LFU缓存
LFU缓存是基于LRU缓存的一个优化,使用频次优化元素命中情况,进一步提高命中率,其余概念不再赘述

基本思路:使用一个双端链表+两个HashMap实现
双端列表存储原始数据、数据在HashMap的key、数据的访问频率

第一个HashMap与LRU的实现类似,存储Key对应链表元素指针,以O(1)的效率定位元素
第二个HashMap用以存储每个访问频率对应的元素集合中最近访问的那个

例:
Put 1 1
Put 2 2
Put 3 3
Get 1
经过三个操作后,第二个HasMap内容如下:

key(访问频率) value(链表内元素指针)
2 元素1
1 元素3(因为它访问时间晚于2号)

具体实现可以参考代码注释

Runtime: 132 ms (beats 80.6%)
Memory Usage: 16 MB

type dataItem struct {
   
	value int
	keyInList int
	frequency int
}

type LFUCache struct {
   
	// 存储每个key对应的链表内指针
	listHashMap  map[int]*list.Element
	// 存储每个访问频率中最新的元素在链表内的指针
	frequencyHashMap  map[int]*list.Element
	// 原始链表
	linkList *list.List
	cap int
}

func Constructor(capacity int) LFUCache {
   
	return LFUCache{
   make(map[int]*list.Element),
		make(map[int]*list.Element),
		list.New(),
		capacity
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
``` class LFUCache { private: int capacity; int minFreq; unordered_map<int, pair<int, int>> cache; // key -> {value, freq} unordered_map<int, list<int>::iterator> freqMap; // freq -> iterator of keys unordered_map<int, list<int>> lruMap; // freq -> list of keys public: LFUCache(int capacity) { this->capacity = capacity; minFreq = 0; } int get(int key) { if (cache.count(key) == 0) { return -1; } int value = cache[key].first; int freq = cache[key].second; freqMap.erase(key); lruMap[freq].erase(freqMap[key]); if (lruMap[freq].empty()) { lruMap.erase(freq); if (freq == minFreq) { minFreq++; } } freq++; cache[key] = {value, freq}; lruMap[freq].push_front(key); freqMap[key] = lruMap[freq].begin(); return value; } void put(int key, int value) { if (capacity == 0) { return; } if (cache.count(key) != 0) { cache[key].first = value; get(key); return; } if (cache.size() == capacity) { int keyToRemove = lruMap[minFreq].back(); lruMap[minFreq].pop_back(); freqMap.erase(keyToRemove); cache.erase(keyToRemove); } minFreq = 1; cache[key] = {value, minFreq}; lruMap[minFreq].push_front(key); freqMap[key] = lruMap[minFreq].begin(); } }; ``` LFU Cache的实现使用了三个哈希表: - `cache` 哈希表:存储键值对和对应的频率。 - `freqMap` 哈希表:存储键值对的频率和对应的迭代器。 - `lruMap` 哈希表:存储键值对的频率和对应的链表。 其中,`cache` 哈希表用于快速查找键值对,`freqMap` 哈希表用于快速查找键值对对应的迭代器,`lruMap` 哈希表用于快速查找某个频率对应的键值对。 LFU Cache有两个方法: - `get` 方法:根据键获取值,如果键不存在则返回 -1。同时更新键值对的频率和链表。 - `put` 方法:插入一个键值对。如果键已存在,则更新值和频率;如果容量已满,则删除频率最小的键值对。同时更新最小频率和链表

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值