美文网首页
LeetCode 460. LFU 缓存

LeetCode 460. LFU 缓存

作者: 陈陈chen | 来源:发表于2021-10-09 15:04 被阅读0次

    1、题目

    image.png

    2、分析

    最麻烦的就是要解决,当容量满的时候,需要删除使用次数最少的那个cache。如果有好几个使用次数都一样,那就淘汰最老的那个数据。

    • 可能有多个key使用的次数一样,所以我们考虑把这些key都放到一个set集合里。
    • 多个key一样的时候,需要淘汰最老的那个数据,因此需要使用链表来处理。

    基于以上两个点,我们可以考虑set和有序链表的结合数据结构:LinkedHashSet<>()

    这里定义三个hashMap:
    HashMap<Integer, Integer> keyToVal; //存k-v映射
    HashMap<Integer, Integer> keyToFreq; //存key和使用次数
    HashMap<Integer, LinkedHashSet<Integer>> freqMap; //使用次数和keys的映射

    3、代码

    class LFUCache {
        HashMap<Integer, Integer> keyToVal;
        HashMap<Integer, Integer> keyToFreq;
        HashMap<Integer, LinkedHashSet<Integer>> freqMap;
        int cap;
        int minFreq;
        public LFUCache(int capacity) {
            cap = capacity;
            minFreq = 0;
            keyToVal = new HashMap<>();
            keyToFreq = new HashMap<>();
            freqMap = new HashMap<>();
        }
        
        public int get(int key) {
            if(!keyToVal.containsKey(key)){
                return -1;
            }
            incFreq(key);
            return keyToVal.get(key);
        }
        
        public void put(int key, int value) {
            if(this.cap == 0) return;
            if(keyToVal.containsKey(key)){
                keyToVal.put(key, value);
                incFreq(key);
                return;
            }
            if(this.cap <= keyToVal.size()){
                removeMinFreq();
            }
            keyToVal.put(key, value);
            keyToFreq.put(key, 1);
            freqMap.putIfAbsent(1, new LinkedHashSet<>());
            freqMap.get(1).add(key);
            this.minFreq = 1;
        }
    
        public void incFreq(int key){
            int freq = keyToFreq.get(key);
            keyToFreq.put(key, freq + 1);
            freqMap.putIfAbsent(freq + 1, new LinkedHashSet<>());
            freqMap.get(freq + 1).add(key);
            freqMap.get(freq).remove(key);
            if(freqMap.get(freq).isEmpty()){
                freqMap.remove(freq);
                if(this.minFreq == freq){
                    this.minFreq = freq + 1;
                }
            }
        }
    
        public void removeMinFreq(){
            LinkedHashSet<Integer> keys = freqMap.get(this.minFreq);
            int delKey = keys.iterator().next();
            keys.remove(delKey);
            if(keys.isEmpty()){
                freqMap.remove(this.minFreq);
            }
            keyToVal.remove(delKey);
            keyToFreq.remove(delKey);
        }
    }
    
    /**
     * 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);
     */
    

    相关文章

      网友评论

          本文标题:LeetCode 460. LFU 缓存

          本文链接:https://www.haomeiwen.com/subject/zvuqoltx.html