設計可以變更的緩存結構(LRU)
設計一種緩存結構, 該結構在構造時確定大小, 假設大小為K, 並有兩個功能:
set(key,value): 將記錄(key,value)插入該結構。
get(key): 返回key對應的value值。
1. set和get方法的時間復雜度為O(1)。
2. 某個key的set或get操作一旦發生, 認為這個key的記錄成了最經常使用的。
3. 當緩存的大小超過K時, 移除最不經常使用的記錄, 即set或get最久遠的。
假設緩存結構的實例是cache, 大小為3, 並依次發生如下行為:
1. cache.set("A",1)。 最經常使用的記錄為("A",1)。
2. cache.set("B",2)。 最經常使用的記錄為("B",2), ("A",1)變為最不經常的。
3. cache.set("C",3)。 最經常使用的記錄為("C",2), ("A",1)還是最不經常的。
4. cache.get("A")。 最經常使用的記錄為("A",1), ("B",2)變為最不經常的。
5. cache.set("D",4)。 大小超過了3, 所以移除此時最不經常使用的記錄("B",2),加入記錄 ("D",4), 並且為最經常使用的記錄, 然後("C",2)變為最不經常使用的記錄
上一題實現了LRU緩存算法, LFU也是一個著名的緩存算法
自行了解之後實現LFU中的set 和 get
要求: 兩個方法的時間復雜度都為O(1)
解:實現:
哈希表(Map)和雙向鏈表(LinkedList)
map中存的是(key, value) = (數據,結點(數據和值)) 當map中存放的是String,Integer.....時,存放的是值,的是自己定義的類型Node......時,實際存放的是引用,即內存地址
雙向鏈表:尾進頭出
當有結點加入的話,加入雙向鏈表尾部, 加入map中,
當進行get操作時,從map中找到那個結點,然後從鏈表中分離出這個結點,然後加到尾部
進行set操作時,在map中進行修改,然後從鏈表中再分離出這個結點,然後加到尾部
當數據超過指定大小之後,在雙向鏈表的頭部刪除,然後找到map中的值,也刪掉
設計可以變更的緩存結構(LRU)