460. LFU 快取
阿新 • • 發佈:2021-12-10
請你為 最不經常使用(LFU)快取演算法設計並實現資料結構。
實現 LFUCache 類:
LFUCache(int capacity) - 用資料結構的容量capacity 初始化物件
int get(int key)- 如果鍵存在於快取中,則獲取鍵的值,否則返回 -1。
void put(int key, int value)- 如果鍵已存在,則變更其值;如果鍵不存在,請插入鍵值對。當快取達到其容量時,則應該在插入新項之前,使最不經常使用的項無效。在此問題中,當存在平局(即兩個或更多個鍵具有相同使用頻率)時,應該去除 最近最久未使用 的鍵。
注意「項的使用次數」就是自插入該項以來對其呼叫 get 和 put 函式的次數之和。使用次數會在對應項被移除後置為 0 。
為了確定最不常使用的鍵,可以為快取中的每個鍵維護一個 使用計數器 。使用計數最小的鍵是最久未使用的鍵。
當一個鍵首次插入到快取中時,它的使用計數器被設定為 1 (由於 put 操作)。對快取中的鍵執行 get 或 put 操作,使用計數器的值將會遞增。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/lfu-cache
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
心之所向,素履以往 生如逆旅,一葦以航import java.util.HashMap; import java.util.LinkedList; import java.util.Map; class LFUCache { private int capacity; private int minFreq; private Map<Integer, Node> keyMap; private Map<Integer, LinkedList<Node>> freqMap; public LFUCache(int capacity) { this.capacity = capacity; this.minFreq = 0; this.keyMap = new HashMap<>(); this.freqMap = new HashMap<>(); } public int get(int key) { Node node = keyMap.get(key); if (node == null) { return -1; } LinkedList<Node> nodes = freqMap.get(node.freq); if (nodes.size() == 1) { freqMap.remove(node.freq); if (minFreq == node.freq) { minFreq++; } } else { nodes.remove(node); } freqMap.computeIfAbsent(++node.freq, k -> new LinkedList<>()).offerFirst(node); return node.value; } public void put(int key, int value) { if (capacity == 0) { return; } Node node = keyMap.get(key); if (node == null) { if (keyMap.size() == capacity) { LinkedList<Node> nodes = freqMap.get(minFreq); keyMap.remove(nodes.pollLast().key); if (nodes.size() == 0) { freqMap.remove(minFreq); } } minFreq = 1; node = new Node(key, value, 1); keyMap.put(key, node); freqMap.computeIfAbsent(node.freq, k -> new LinkedList<>()).offerFirst(node); } else { node.value = value; LinkedList<Node> nodes = freqMap.get(node.freq); if (nodes.size() == 1) { freqMap.remove(node.freq); if (minFreq == node.freq) { minFreq++; } } else { nodes.remove(node); } freqMap.computeIfAbsent(++node.freq, k -> new LinkedList<>()).offerFirst(node); } } } class Node { int key; int value; int freq; public Node(int key, int value, int freq) { this.key = key; this.value = value; this.freq = freq; } } /** * 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); */