如果設計和實現一個LFU(least frequently used )

文章目錄

1.LFU 

2. java實現LFU:


1.LFU 

            


2. java實現LFU:

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;

/**
 * @author: zhangyu
 */
public class LFUCache4601 {
    Map<Integer, int[]> cache;  // 存儲緩存的內容
    Map<Integer, LinkedHashSet<int[]>> frequentlyMap; // 存儲每個頻次對應的雙向鏈表
    int size;
    int capacity;
    int min; // 存儲當前最小頻次

    public LFUCache4601(int capacity) {
        cache = new HashMap<>(capacity);
        frequentlyMap = new HashMap<>();
        this.capacity = capacity;
    }

    /**
     * 獲取元素
     *
     * @param key key
     * @return value
     */
    public int get(int key) {
        int[] node = cache.get(key);
        if (node == null) {
            return -1;
        }
        updateNode(node);
        return node[1];
    }

    /**
     * 插入一個值
     *
     * @param key   key
     * @param value value
     */
    public void put(int key, int value) {
        if (capacity == 0) {
            return;
        }
        int[] node = cache.get(key);
        if (node != null) {
            // 更新value
            node[1] = value;
            updateNode(node);
        } else {
            if (size == capacity) {
                int[] deadNode = removeNode();
                cache.remove(deadNode[0]);
                size--;
            }
            int[] newNode = new int[]{key, value, 1};
            cache.put(key, newNode);
            addNode(newNode);
            size++;
        }
    }

    /**
     * 更新頻次
     *
     * @param node 節點
     */
    public void updateNode(int[] node) {
        int freq = node[2];
        LinkedHashSet<int[]> set = frequentlyMap.get(freq);
        set.remove(node);
        if (freq == min && set.size() == 0) {
            min = freq + 1;
        }
        // 加入新freq對應的鏈表
        node[2]++;
        LinkedHashSet<int[]> newSet = frequentlyMap.get(freq + 1);
        if (newSet == null) {
            newSet = new LinkedHashSet<>();
            frequentlyMap.put(freq + 1, newSet);
        }
        newSet.add(node);
    }

    /**
     * 增加元素
     *
     * @param node 節點
     */
    public void addNode(int[] node) {
        LinkedHashSet<int[]> set = frequentlyMap.get(1);
        if (set == null) {
            set = new LinkedHashSet<>();
            frequentlyMap.put(1, set);
        }
        set.add(node);
        min = 1;
    }

    /**
     * 刪除第一個元素
     *
     * @return 返回第一個元素
     */
    public int[] removeNode() {
        LinkedHashSet<int[]> set = frequentlyMap.get(min);
        int[] deadNode = set.iterator().next();
        set.remove(deadNode);
        return deadNode;
    }
}

時間複雜度:O(1)

空間複雜度: O(1)

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