1. 程式人生 > 實用技巧 >leetcode刷題筆記一百四十六題 LRU快取機制

leetcode刷題筆記一百四十六題 LRU快取機制

leetcode刷題筆記一百四十六題 LRU快取機制

源地址:146. LRU快取機制

問題描述:

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

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

進階:

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

示例:

LRUCache cache = new LRUCache( 2 /* 快取容量 */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 該操作會使得關鍵字 2 作廢
cache.get(2); // 返回 -1 (未找到)
cache.put(4, 4); // 該操作會使得關鍵字 1 作廢
cache.get(1); // 返回 -1 (未找到)
cache.get(3); // 返回 3
cache.get(4); // 返回 4

//LRU快取機制需要藉助HashMap實現O(1)級別的操作,同時需要維護一個列表,用於記錄使用順序
import scala.collection.mutable
class LRUCache(_capacity: Int) {
    var hm = mutable.HashMap.empty[Int, Int]
    var lb = mutable.ListBuffer.empty[Int]
    //當前不重複數值容量,最大為capacity
    var size = 0
    //最大容量
    var capacity = _capacity

    def get(key: Int): Int = {
        //key值已經塞入
        if (hm.contains(key)){
            val li = lb.indexOf(key)
            //更新lb中key值位置到末尾,代表最近訪問
            lb.remove(li)
            lb += key
            return hm(key)
        }
        //get不到,返回-1
        return -1
    }

    def put(key: Int, value: Int) {
        //已塞入key,只需更新key到末尾即可
        if (hm.contains(key)){
            hm(key) = value
            val li = lb.indexOf(key)
            lb.remove(li)
            lb += key
        }
        else{
            //如果此時已達容量上限,刪去lb的頭部元素
            if (size == capacity){
                val lh = lb.head
                hm -= lh
                lb.remove(0)
            }
            //未達上限,更新size
            else size += 1
            //將新key新增
            hm(key) = value
            lb += key
        }
    }
}

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