LRU緩存機制 JAVA

運用你所掌握的數據結構,設計和實現一個 LRU (最近最少使用) 緩存機制。它應該支持以下操作: 獲取數據 get 和 寫入數據 put 。

獲取數據 get(key) - 如果密鑰 (key) 存在於緩存中,則獲取密鑰的值(總是正數),否則返回 -1。
寫入數據 put(key, value) - 如果密鑰已經存在,則變更其數據值;如果密鑰不存在,則插入該組「密鑰/數據值」。當緩存容量達到上限時,它應該在寫入新數據之前刪除最久未使用的數據值,從而爲新的數據值留出空間。

你是否可以在 O(1) 時間複雜度內完成這兩種操作?

來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/lru-cache 著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

主要思想: 利用HashMap和鏈表構建LRU,新訪問的節點放在鏈表的末尾,最久未使用的節點訪問頭部

class LRUCache {
    // 記錄當前存儲了多少個鍵值對
    private int size = 0;
    // 初始容量
    private int capacity = 0;
//    方便快速定位節點
    Map<Integer,Node> cache = null;
//    頭結點
    private Node head = null;
//    尾結點
    private Node tail = null;
    public LRUCache(int capacity) {
        head = new Node(-1);
        tail = new Node(-1);
        head.post = tail;
        tail.pre = head;
        this.capacity = capacity;
        size = 0;
        cache = new HashMap<>();
    }

    public int get(int key) {
        Node tem = cache.get(key);
        if (tem!=null) {
            moveToTail(tem);   // 表明新訪問的節點在最後
            return tem.value;
        }
        return -1;
    }

    public void put(int key, int value) {
        Node tem = cache.get(key);
        if (tem==null){    //沒找到節點,則新增節點
            tem = new Node();
            tem.key = key;
            tem.value = value;
            cache.put(key,tem);
            addToTail(tem);    //增加到最後
            size++;
            if (size>capacity){   //超出容量則刪除最近沒有訪問的節點,也就是頭結點
                Node h = removeHead();
                cache.remove(h.key);
                size--;
            }
        }else{
            tem.value = value;
            moveToTail(tem);
        }
    }
    //當前節點移動到尾部
    private void moveToTail(Node tem){
        Node pre = tem.pre;
        Node next = tem.post;
        pre.post = next;
        next.pre = pre;
        tem.post = tail;
        tem.pre = tail.pre;
        tail.pre.post = tem;
        tail.pre = tem;
    }
//    在尾部新增節點
    private void addToTail(Node tem){
        tem.post = tail;
        tem.pre = tail.pre;
        tail.pre.post = tem;
        tail.pre = tem;
    }
//刪除頭部最近沒有被訪問的節點
    private Node removeHead(){
        Node tem = head.post;
        head.post = head.post.post;
        head.post.pre = head;
        return tem;
    }
}

class Node{
    int value;
    int key;
    Node pre;
    Node post;
    Node(int x){value = x;}
    Node(){}

}

使用LinkedHashMap實現LRU緩存機制

class LRUCache {
    LinkedHashMap<Integer,Integer> cache = null;
    private final int MAX_CACHE_SIZE;
    private final float DEFAULT_LOAD_FACTORY = 1.0f;

    public LRUCache(int capacity) {
        MAX_CACHE_SIZE = capacity;
        cache = new LinkedHashMap<Integer, Integer>(capacity, DEFAULT_LOAD_FACTORY, true) {
            @Override
            protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
                return size() > MAX_CACHE_SIZE;
            }
        };

    }

    public int get(int key) {
        Integer tem = cache.get(key);
        if (tem!=null) {
            return tem;
        }
        return -1;
    }

    public void put(int key, int value) {
        cache.put(key,value);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章