Design and implement a data structure forLeast Frequently Used (LFU)cache. It should support the following operations:getandput.
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 leastrecentlyused key would be evicted.
Follow up:
Could you do both operations inO(1)time complexity?
我的实现绝对不是O(1),O(1)的看了一下discuss,好象是用2个hashmap,一个<key, value>一个<key, node>,然后每个node是个doublelinkedlist,还用了linkedhashset。各种复杂,不明觉厉。过了一段时间做过432那题然后google了一番,终于发现那个数据结构就是实现LFU的数据结构。基本上就是hashmap保存key和node,每个node都存了access次数和对应的hashSet(linkedHashset,因为删除用得最小的值时,old的value会首先被删,这就刚好是linkedhashset的特性,用iterator,先进去的先出来)如果某一个值被access多一次的话,就remove from set,然后插到下一个节点which has + 1 frequency。
publicclassLFUCache {classNode {int key;int val;int freq;long ts;publicNode(int k,int v,int f,long t) { key = k; val = v; freq = f; ts = t; } }int cap;//<key, node>HashMap<Integer,Node> hm;PriorityQueue<Node> freqQ;long systime;publicLFUCache(int capacity) { cap = capacity; hm =newHashMap<>(); systime =0L; freqQ =newPriorityQueue(newComparator<Node>() {publicint compare(Node n1,Node n2) {if (n1.freq==n2.freq) {return (int)(n1.ts-n2.ts); }returnn1.freq-n2.freq; } }); }publicintget(int key) {if (cap <1) { // don't need this ?return-1; }if (!hm.containsKey(key)) {return-1; }// if exist update freq & tsNode cur =hm.get(key);// need to remove & inseart again to update priorityQueue, or reordering won't kick infreqQ.remove((Object)cur); cur.freq=cur.freq+1; // cur.freq++;cur.ts= systime++;freqQ.offer(cur);returncur.val; }publicvoidput(int key,int value) {if (cap <1) {return; }if (get(key)!=-1) {Node cur =hm.get(key); // combine into onecur.val= value; // hm.get(key).val = value;return; }// if it's full, remove least frequnt oneif (freqQ.size() == cap) {Node old =freqQ.poll();hm.remove(old.key); }// need to create new node and inseartNode newNode =newNode(key, value,1, systime++);hm.put(key, newNode);freqQ.offer(newNode); }}/** * 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); */