1. 程式人生 > 實用技巧 >LinkedHashMap實現 LRU

LinkedHashMap實現 LRU

一、leetcode 題目

運用你所掌握的資料結構,設計和實現一個 LRU (最近最少使用) 快取機制 。
實現 LRUCache 類:

LRUCache(int capacity) 以正整數作為容量capacity 初始化 LRU 快取
int get(int key) 如果關鍵字 key 存在於快取中,則返回關鍵字的值,否則返回 -1 。
void put(int key, int value)如果關鍵字已經存在,則變更其資料值;如果關鍵字不存在,則插入該組「關鍵字-值」。當快取容量達到上限時,它應該在寫入新資料之前刪除最久未使用的資料值,從而為新的資料值留出空間。

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

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

LRU 本身是一個作業系統的頁面置換演算法,least rencently used,也就是置換的時候置換掉那個最近使用的最少的,其實實現更加簡化,使用一次就將它放到棧頂,移除的時候其實就是移除棧底的元素。

這個題目的重點在於要求 O(1) 時間複雜度,在對於 put 和 get 來說,O(1) 時間複雜度很容易想到 hashmap,但是對於 LRU 來說,需要元素有序,java 裡提供了一個 linkedhashmap 類,原始碼的註釋裡就寫了可以用來實現 cache。

class LRUCache {
    int capacity;
    LinkedHashMap<Integer, Integer> cache;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        cache = new LinkedHashMap<Integer, Integer>(capacity, 0.75f, true){
            @Override
            protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
                return cache.size() > capacity;
            }
        };
    }
    
    public int get(int key) {
        return cache.getOrDefault(key, -1);
    }
    
    public void put(int key, int value) {
        cache.put(key, value);
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

二、LinkedHashMap原始碼

基本思路就是 HashMap + 雙向連結串列,在 Map 的基礎上作出有序。放上一篇部落格參考:

https://www.jianshu.com/p/8f4f58b4b8ab