日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

460. LFU 缓存

發(fā)布時(shí)間:2023/11/29 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 460. LFU 缓存 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

460. LFU 緩存

請(qǐng)你為 最不經(jīng)常使用(LFU)緩存算法設(shè)計(jì)并實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)。

實(shí)現(xiàn) LFUCache 類:

  • LFUCache(int capacity) - 用數(shù)據(jù)結(jié)構(gòu)的容量 capacity 初始化對(duì)象
  • int get(int key) - 如果鍵存在于緩存中,則獲取鍵的值,否則返回 -1。
  • void put(int key, int value) - 如果鍵已存在,則變更其值;如果鍵不存在,請(qǐng)插入鍵值對(duì)。當(dāng)緩存達(dá)到其容量時(shí),則應(yīng)該在插入新項(xiàng)之前,使最不經(jīng)常使用的項(xiàng)無(wú)效。在此問(wèn)題中,當(dāng)存在平局(即兩個(gè)或更多個(gè)鍵具有相同使用頻率)時(shí),應(yīng)該去除 最近最久未使用 的鍵。
    注意「項(xiàng)的使用次數(shù)」就是自插入該項(xiàng)以來(lái)對(duì)其調(diào)用 get 和 put 函數(shù)的次數(shù)之和。使用次數(shù)會(huì)在對(duì)應(yīng)項(xiàng)被移除后置為 0 。

為了確定最不常使用的鍵,可以為緩存中的每個(gè)鍵維護(hù)一個(gè) 使用計(jì)數(shù)器 。使用計(jì)數(shù)最小的鍵是最久未使用的鍵。

當(dāng)一個(gè)鍵首次插入到緩存中時(shí),它的使用計(jì)數(shù)器被設(shè)置為 1 (由于 put 操作)。對(duì)緩存中的鍵執(zhí)行 get 或 put 操作,使用計(jì)數(shù)器的值將會(huì)遞增。

示例:輸入: ["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 的使用計(jì)數(shù) // 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 ,因?yàn)?cnt(2)=1 ,使用計(jì)數(shù)最小// 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

解題思路

將鍵值對(duì)和使用頻率封裝成為node對(duì)象,使用map記錄key和node的映射關(guān)系。對(duì)于每個(gè)使用頻率,維護(hù)一個(gè)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);*/

總結(jié)

以上是生活随笔為你收集整理的460. LFU 缓存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。