460. LFU 缓存
生活随笔
收集整理的這篇文章主要介紹了
460. LFU 缓存
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
460. LFU 緩存
請你為 最不經常使用(LFU)緩存算法設計并實現數據結構。
實現 LFUCache 類:
- LFUCache(int capacity) - 用數據結構的容量 capacity 初始化對象
- int get(int key) - 如果鍵存在于緩存中,則獲取鍵的值,否則返回 -1。
- void put(int key, int value) - 如果鍵已存在,則變更其值;如果鍵不存在,請插入鍵值對。當緩存達到其容量時,則應該在插入新項之前,使最不經常使用的項無效。在此問題中,當存在平局(即兩個或更多個鍵具有相同使用頻率)時,應該去除 最近最久未使用 的鍵。
注意「項的使用次數」就是自插入該項以來對其調用 get 和 put 函數的次數之和。使用次數會在對應項被移除后置為 0 。
為了確定最不常使用的鍵,可以為緩存中的每個鍵維護一個 使用計數器 。使用計數最小的鍵是最久未使用的鍵。
當一個鍵首次插入到緩存中時,它的使用計數器被設置為 1 (由于 put 操作)。對緩存中的鍵執行 get 或 put 操作,使用計數器的值將會遞增。
示例:輸入: ["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]] 輸出: [null, null, null, 1, null, -1, 3, null, -1, 3, 4]解釋: // cnt(x) = 鍵 x 的使用計數 // cache=[] 將顯示最后一次使用的順序(最左邊的元素是最近的) LFUCache lFUCache = new LFUCache(2); lFUCache.put(1, 1); // cache=[1,_], cnt(1)=1 lFUCache.put(2, 2); // cache=[2,1], cnt(2)=1, cnt(1)=1 lFUCache.get(1); // 返回 1// cache=[1,2], cnt(2)=1, cnt(1)=2 lFUCache.put(3, 3); // 去除鍵 2 ,因為 cnt(2)=1 ,使用計數最小// cache=[3,1], cnt(3)=1, cnt(1)=2 lFUCache.get(2); // 返回 -1(未找到) lFUCache.get(3); // 返回 3// cache=[3,1], cnt(3)=2, cnt(1)=2 lFUCache.put(4, 4); // 去除鍵 1 ,1 和 3 的 cnt 相同,但 1 最久未使用// cache=[4,3], cnt(4)=1, cnt(3)=2 lFUCache.get(1); // 返回 -1(未找到) lFUCache.get(3); // 返回 3// cache=[3,4], cnt(4)=1, cnt(3)=3 lFUCache.get(4); // 返回 4// cache=[3,4], cnt(4)=2, cnt(3)=3解題思路
將鍵值對和使用頻率封裝成為node對象,使用map記錄key和node的映射關系。對于每個使用頻率,維護一個linkedSet記錄使用的順序,就可以做到每次刪除使用頻率最少的并且最近未使用的
代碼
class LFUCache {Map<Integer,Node> map=new HashMap();int size,cap;int min=1;Map<Integer,LinkedHashSet<Node>> freq=new HashMap<>();public LFUCache(int capacity) {size=0;cap=capacity;}public int get(int key) {if(!map.containsKey(key))return -1;Node node = map.get(key);freq.get(node.cnt).remove(node);if(node.cnt==min&&freq.get(min).isEmpty())min=node.cnt+1;node.cnt++;if(!freq.containsKey(node.cnt))freq.put(node.cnt,new LinkedHashSet<>());freq.get(node.cnt).add(node);return node.value;}public void put(int key, int value) {if(cap==0) return;if(map.containsKey(key)){Node node = map.get(key);freq.get(node.cnt).remove(node);if(node.cnt==min&&freq.get(min).isEmpty())min=node.cnt+1;node.cnt++;node.value=value;}else{if(size==cap){LinkedHashSet<Node> set = freq.get(min);Node de = set.iterator().next();set.remove(de);map.remove(de.key);size--;}Node node=new Node(key,value);map.put(key,node);min=1;size++;}Node cur=map.get(key);if(!freq.containsKey(cur.cnt))freq.put(cur.cnt,new LinkedHashSet<>());freq.get(cur.cnt).add(cur);}class Node{int cnt,key,value;Node(int k,int v){key=k;value=v;cnt=1;}}}/*** 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);*/總結
以上是生活随笔為你收集整理的460. LFU 缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到大南瓜是什么意思
- 下一篇: 662. 二叉树最大宽度