LeetCode 460. LFU缓存

请你为 最不经常使用(LFU)缓存算法设计并实现数据结构。它应该支持以下操作:get 和 put。

  • get(key)- 如果键存在于缓存中,则获取键的值(总是正数),否则返回 -1。
  • put(key, value)- 如果键已存在,则变更其值;如果键不存在,请插入键值对。当缓存达到其容量时,则应该在插入新项之前,使最不经常使用的项无效。在此问题中,当存在平局(即两个或更多个键具有相同使用频率)时,应该去除最久未使用的键。
  • 项的使用次数」就是自插入该项以来对其调用 getput函数的次数之和。使用次数会在对应项被移除后置为 0 。

进阶:

  • 你是否可以在 O(1) 时间复杂度内执行两项操作?

示例:

LFUCache cache = new LFUCache( 2 /* capacity (缓存容量) */ );cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // 返回 1
cache.put(3, 3);    // 去除 key 2
cache.get(2);       // 返回 -1 (未找到key 2)
cache.get(3);       // 返回 3
cache.put(4, 4);    // 去除 key 1
cache.get(1);       // 返回 -1 (未找到 key 1)
cache.get(3);       // 返回 3
cache.get(4);       // 返回 4

代码

class Node:def __init__(self, key, val, freq=1, prev=None, next=None):self.key = keyself.val = valself.freq = freqself.prev = prevself.next = nextclass LinkedNodeList:def __init__(self):self.head = Noneself.tail = Noneself.size = 0def __len__(self):return self.sizedef append(self, node):if self.head is None and self.tail is None:self.head = self.tail = nodeelse:self.tail.next = nodenode.prev = self.tailself.tail = nodeself.size += 1def remove(self, node):assert len(self) >= 1if node is self.head and node is self.tail:self.head = Noneself.tail = Noneelse:if node is self.head:self.head = node.nextnode.next = Noneelif node is self.tail:self.tail = node.prevnode.prev = Noneelse:prev = node.prevnext = node.nextprev.next = nextnext.prev = prevnode.prev = Nonenode.next = Noneself.size -= 1class LFUCache(object):def __init__(self, capacity):""":type capacity: int"""self.heap = []self.capacity = capacityself.cnt = 0self.freq_mapping = {}self.key_mapping = {}        @propertydef min_freq(self):return min(self.freq_mapping.keys())def _get_existing_node(self, key):node = self.key_mapping[key]old_freq = node.freqnew_freq = old_freq + 1linked_list = self.freq_mapping[old_freq]linked_list.remove(node)if len(linked_list) == 0:self.freq_mapping.pop(old_freq, None)linked_list = self.freq_mapping.get(new_freq, None) or LinkedNodeList()node.freq = new_freqlinked_list.append(node)self.freq_mapping[new_freq] = linked_listreturn nodedef _put_new_node(self, key, value):linked_list = self.freq_mapping.get(1, None) or LinkedNodeList()node = Node(key, value)self.key_mapping[key] = nodelinked_list.append(node)self.freq_mapping[1] = linked_listself.cnt += 1        def get(self, key):""":type key: int:rtype: int"""val = -1if key in self.key_mapping:node = self._get_existing_node(key)val = node.valreturn val        def put(self, key, value):""":type key: int:type value: int:rtype: None"""if self.capacity == 0:returnif key in self.key_mapping:node = self._get_existing_node(key)node.val = valueelse:if self.cnt < self.capacity:self._put_new_node(key, value)else:min_freq = self.min_freqlinked_list = self.freq_mapping[min_freq]head = linked_list.headself.key_mapping.pop(head.key)linked_list.remove(head)del headif len(linked_list) == 0:self.freq_mapping.pop(min_freq)self._put_new_node(key, value)        # Your LFUCache object will be instantiated and called as such:
# obj = LFUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
  • LFU维护着N个使用频率的双向链表,命中的数据,会随着freq的增加,而被重新放置于更大的freq对应的双向链表中(具体的位置是尾部),而那些freq频率最小的双向链表,则是当缓存超出时,考虑删除的数据;由于对于每一个双向链表,新数据总是append到尾部,所以在删除数据的时候,删除的是最小频率的双向链表的表头;

学习笔记 | LeetCode 460. LFU缓存相关推荐

  1. ​ leetcode 460. LFU 缓存 hard​

    leetcode 460. LFU 缓存  hard 题目描述: 请你为 最不经常使用(LFU)缓存算法设计并实现数据结构. 实现 LFUCache 类: LFUCache(int capacity) ...

  2. LeetCode 460. LFU缓存(哈希双链表)

    1. 题目 设计并实现最不经常使用(LFU)缓存的数据结构.它应该支持以下操作:get 和 put. get(key) - 如果键存在于缓存中,则获取键的值(总是正数),否则返回 -1. put(ke ...

  3. LeetCode 460. LFU 缓存 -- 哈希查询+双向链表

    LFU 缓存 困难 634 相关企业 请你为 最不经常使用(LFU)缓存算法设计并实现数据结构. 实现 LFUCache 类: LFUCache(int capacity) - 用数据结构的容量 ca ...

  4. LeetCode 460. LFU缓存

    文章目录 题目描述 思路 实现 解法二 扩展 题目描述 实现一个LFU缓存(Least Frequently Used). 在需要移除元素时,移除最近访问频率最低的.可以对每个元素增加一个计数器,访问 ...

  5. Leetcode 460. LFU 缓存

    题目重述 请你为 最不经常使用(LFU)缓存算法设计并实现数据结构. 实现 LFUCache 类: LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象 i ...

  6. lfu算法c语言,LeetCode算法系列 460. LFU 缓存机制

    力扣原题 460. LFU 缓存机制 请你为 最不经常使用(LFU)缓存算法设计并实现数据结构. 实现 LFUCache 类:LFUCache(int capacity) - 用数据结构的容量 cap ...

  7. 460. LFU 缓存

    460. LFU 缓存 请你为 最不经常使用(LFU)缓存算法设计并实现数据结构. 实现 LFUCache 类: LFUCache(int capacity) - 用数据结构的容量 capacity ...

  8. 微信小程序开发:学习笔记[9]——本地数据缓存

    微信小程序开发:学习笔记[9]--本地数据缓存 快速开始 说明 本地数据缓存是小程序存储在当前设备上硬盘上的数据,本地数据缓存有非常多的用途,我们可以利用本地数据缓存来存储用户在小程序上产生的操作,在 ...

  9. Manacher算法学习笔记 | LeetCode#5

    Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...

最新文章

  1. 广度深度都要,亚马逊是如何推动 Alexa 内生成长的?
  2. python代码写好了怎么运行视频-Python的初学者你现在可以自己“看”到代码的运行了!...
  3. python官网下载步骤64位-电脑64位怎么下载python
  4. Spring Boot配置Mysql后无法根据java实体类生成table
  5. Python数据结构学习笔记——树和图
  6. abp vnext2.0核心组件之.Net Core默认DI组件切换到AutoFac源码解析
  7. java VM argument_java之program arguments与VM arguments
  8. python twisted教程_Python Twisted系列教程1:Twisted理论基础
  9. delphi webbrowser 对象不支持_建模初学者,那些你可能还不知道的10个ZBrush小技巧!【值得收藏】...
  10. Map集合HashMap,TreeMap
  11. cups支持的打印机列表_在Mac上怎样更新打印机软件?
  12. c++ 17 新特性理解
  13. python函数进阶小结_Python 函数3000字使用总结
  14. 使用matlab时括号附近出现红色波浪线“使用的MATLAB语法可能无效”提示
  15. 线性代数 n维向量思维导图总结(看这一张就完事了)
  16. 电路设计基础知识(一)[转]
  17. vue鼠标右击事件@contextmenu.prevent
  18. 固态硬盘是什么接口_电脑M.2接口讲究多:读懂固态硬盘完整规格
  19. 指纹录入和指纹解锁流程
  20. 鼠标坏了怎么用键盘操作鼠标

热门文章

  1. html制作我的世界,【我的世界】迷你世界SkyPixel像素天空HTML官方网站源代码
  2. 如何将一个网页快速生成打包app
  3. 竖屏视频文件怎么快速转换
  4. 2022-2028全球肿块破碎机行业调研及趋势分析报告
  5. Latex基本操作 | 在引用文献后面加上DOI号
  6. mysql update锁表_MySQL执行update语句是锁行还是锁表分析
  7. C语言实验指导 P20 齿轮啮合
  8. 知识图谱初识-什么是知识图谱
  9. java mysql 工具类_Java SE 之 数据库操作工具类(DBUtil)设计
  10. swift编程语言基础教程 中文版