LFU Cache:最不经常使用页置换算法
来源:互联网 发布:js 点击div刷新页面 编辑:程序博客网 时间:2024/05/20 12:51
Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: get
and put
.
get(key)
- Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.put(key, value)
- Set or insert the value if the key is not already present. When the cache reaches its capacity, it should invalidate the least frequently used item before inserting a new item. For the purpose of this problem, when there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted.
Follow up:
Could you do both operations in O(1) time complexity?
Example:
LFUCache cache = new LFUCache( 2 /* capacity */ );cache.put(1, 1);cache.put(2, 2);cache.get(1); // returns 1cache.put(3, 3); // evicts key 2cache.get(2); // returns -1 (not found)cache.get(3); // returns 3.cache.put(4, 4); // evicts key 1.cache.get(1); // returns -1 (not found)cache.get(3); // returns 3cache.get(4); // returns 4思路:LFU,就是最不经常使用页置换算法。难点:
一:O(1)访问速度,所以要使用hash,形式是<key,val>
二:更新访问频率,而且也要O(1),所以也要使用hash,形式是<key,count>
三:无多余空间时,删除访问频率最低的元素,所以对于每个count也要记录下,形式是<count,linkededhashset>,因为linkedhashset有序,可以对应当访问次数相同时按先后次序剔除(即删除链表开头元素)
四:存在<key,old> -> <key,new>这种情况,所以除了更近=新键值对以外,也要讲访问频率更新
原理都明白,可真正写的时候真的是困难!!!
public class LFUCache {int min = -1;// 表示当前最小的访问频率等级HashMap<Integer, Integer> val = new HashMap<Integer, Integer>();// key,valHashMap<Integer, Integer> counts = new HashMap<Integer, Integer>();// key,countsHashMap<Integer, LinkedHashSet<Integer>> level = new HashMap<Integer, LinkedHashSet<Integer>>();// count,set// 记录每个访问频率等级集下的keyint size = 0;public LFUCache(int capacity) {this.size = capacity;level.put(1, new LinkedHashSet<Integer>());min = 1;//最小值的作用是为了当空间不足时,找到访问频率最低的那个集中最靠前(出现最早)的元素而设置}public int get(int key) {if (!val.containsKey(key)) {// key不存在,返回-1// System.out.println("key不存在");return -1;}int count = (counts.get(key) == null) ? 0 : counts.get(key);// 记录频率// System.out.println(count);int result = val.get(key);// 获取返回值counts.put(key, count + 1);// 记录下新访问频率level.get(count).remove(key);// 剔除原访问等级下,包含的该keyif (!level.containsKey(count + 1)) {// 如果将要更新的访问等级还为未出现过,创建一个新的访问等级集level.put((count + 1), new LinkedHashSet<Integer>());}level.get((count + 1)).add(key);// 更新访问等级集中的keyif (min == count && level.get(count).size() == 0)// 修改最小值{min++;}// System.out.println("get "+key+" :"+val);return result;}public void put(int key, int value) {if (size <= 0)return;// 没有空间if (val.containsKey(key)) {// 仅仅是更新值,包括空间未满与空间刚刚号重慢两种情况,仅需要更新val值与访问次数(相当于一次get)val.put(key, value);get(key);return;}if ((val.size() >= size))// 空间不足,先移除最近访问次数最低的元素{// System.out.println(min);int oldkey = level.get(min).iterator().next();// System.out.println("oldkey:"+oldkey);val.remove(oldkey);counts.remove(oldkey);level.get(min).remove(oldkey);// System.out.println("after remove ,val:"+val);// System.out.println("after remove ,count:"+counts);}// 添加新元素,此时或者一开始就有剩余空间,或者因为空间已满而清理出空间后有剩余空间val.put(key, value);counts.put(key, 1);level.get(1).add(key);min = 1;// System.out.println("put "+key+" :"+val);} public static void main(String[] args){ StringBuilder sb = new StringBuilder(); //["LFUCache","put","put","get","put","get","get","put","get","get","get"] //[[2],[1,1],[2,2],[1],[3,3],[2],[3],[4,4],[1],[3],[4]] /* LFUCache obj = new LFUCache(2); obj.put(1,1); obj.put(2,2); sb.append(obj.get(1)); obj.put(3,3); sb.append(obj.get(2)); sb.append(obj.get(3)); obj.put(4,4); sb.append(obj.get(1)); sb.append(obj.get(3)); sb.append(obj.get(4)); System.out.println(sb.toString()); */ LFUCache obj = new LFUCache(0); obj.put(0,0); sb.append(obj.get(0)); System.out.println(sb.toString()); }}
- LFU Cache:最不经常使用页置换算法
- 亲自操刀:cache页面置换算法LRU AND LFU
- 复杂度为O(1)的最不常用[LFU]缓存算法
- OS 请求调页存储管理方式的FIFO、LRU、OPT、LFU置换算法模拟
- 460. LFU Cache O(1)算法 C++
- cache FIFO, LFU 算法 讨论与实现
- LFU Cache
- LFU Cache
- 缓存算法(页面置换算法)-FIFO、LFU、LRU
- 缓存算法(页面置换算法)-FIFO、LFU、LRU
- 缓存算法(页面置换算法)-FIFO、LFU、LRU
- 缓存算法(页面置换算法)-FIFO、LFU、LRU
- 缓存算法(页面置换算法)-FIFO、LFU、LRU
- 页面置换算法--LFU算法实现-O(1)时间复杂度
- 缓存算法(页面置换算法)-FIFO、LFU、LRU
- 缓存算法(页面置换算法)-FIFO、LFU、LRU
- [Leetcode-146] LRU Cache 最近最少使用页面置换算法
- LFU算法
- spfa(模板)
- unity接入unity Ads详细流程
- netty内存泄漏,困扰了好几天的问题找到原文了
- angular依赖注入
- 手把手教你Shape,Selector实战--打造底部Tab菜单
- LFU Cache:最不经常使用页置换算法
- 2018春节倒计时
- Longest Increasing Path in a Matrix
- 启明星第八周学习总结
- Java —— 数据统计图的实现(柱形图,饼图,折线图)
- 堆排(模板)
- 数据结构第七周项目-排队看病模拟(队列)
- 广告拦截之Adblock Plus 安装
- bzoj2157