LFU算法的應用及實現

概述

實現

  • 這裏可以完全基於HashMap來完成設計,源碼如下:
public class LFUCache {

    private int cap;
    private int minFreq;
    private HashMap<Integer, Integer> map;
    private HashMap<Integer, Integer> freqMap;
    private HashMap<Integer, LinkedHashSet<Integer>> freqList;

    /**
     * cap表示容量
     * minFreq表示目前集合裏出現最低的頻次,
     * map記錄每個key-value,
     * freqMap記錄每個key的出現的頻次,
     * freqList記錄每個頻次對應的key-list集合
     *
     * @param capacity
     */
    public LFUCache(int capacity) {
        minFreq = 1;
        cap = capacity;
        map = new HashMap<>();
        freqMap = new HashMap<>();
        freqList = new HashMap<>();
    }

    public int get(int key) {
        if (!map.containsKey(key)) {
            return -1;
        }
        int count = freqMap.get(key);
        freqMap.put(key, count + 1);
        freqList.get(count).remove(key);
        LinkedHashSet<Integer> minFreqList = freqList.get(minFreq);
        if (minFreqList == null || minFreqList.size() == 0) {
            minFreq++;
        }

        freqList.merge(count + 1, new LinkedHashSet<Integer>() {{
                add(key);
            }},
            (pre, one) -> {
                pre.addAll(one);
                return pre;
            }
        );
        return map.get(key);
    }

    public void put(int key, int value) {
        if (cap <= 0) {
            return;
        }
        if (get(key) != -1) {
            map.put(key, value);
            return;
        }

        //新增元素如果超過容量,去除最低頻次元素
        if (map.size() >= cap) {
            Integer removeKey = freqList.get(minFreq).iterator().next();
            map.remove(removeKey);
            freqMap.remove(removeKey);
            freqList.get(minFreq).remove(removeKey);
        }
        minFreq = 1;
        map.put(key, value);
        freqMap.put(key, 1);
        freqList.merge(1, new LinkedHashSet<Integer>() {{
                add(key);
            }},
            (pre, one) -> {
                pre.addAll(one);
                return pre;
            }
        );
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章