【LeetCode】LRU Cache 解題報告
題外話:才連續寫了幾篇部落格,部落格排名竟然就不再是“千里之外”了,已經進入2萬名之內了。再接再厲,加油!
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get
and set
.
get(key)
- Get the value (will always be positive) of the key if the
key exists in the cache, otherwise return -1.set(key, value)
設計並實現一個支援get和set操作的快取:
get(key) - 存在時返回其值,否則返回-1;
set(key) - 不存在時插入新值,存在時更新其值,注意當容量滿時,需刪除最長時間沒有訪問的key,將其刪除,並插入新的key。
==================== Map+List 實現法 ====================
【思路】
用map結構實現<key, value>的儲存與讀取。
用一個list來記錄key被訪問時間的久遠,最近被訪問的放在list的最後,list中的第一個key表示最長時間沒被訪問的。
【Java程式碼】
class LRUCache { HashMap<Integer, Integer> map; ArrayList<Integer> list; int capacity; public LRUCache(int capacity) { map = new HashMap<Integer, Integer>(capacity); list = new ArrayList<Integer>(capacity); this.capacity = capacity; } public int get(int key) { if (map.get(key) == null) return -1; list.remove(new Integer(key)); list.add(key); return map.get(key); } public void set(int key, int value) { if (map.get(key) != null) {//原來存在key map.put(key, value); list.remove(new Integer(key)); list.add(key); } else {//原來不存在key if (map.size() < capacity) {//容量不滿 map.put(key, value); list.add(key); } else {//容量滿 int leastkey = list.remove(0); list.add(key); map.remove(leastkey); map.put(key, value); } } } }
【注意點】
題目要求是Least Recently Used,不僅 set 時要更新list,get 時也要更新list。
set 時,需先判斷map中有無該值,若沒有再判斷map是否滿了;如果反過來,即先判斷map是否為滿,再判斷map中有無該值,這樣就錯了。
因為如果map滿時,其中有該值,直接更新就好,而先判斷map是否為滿的話,就會導致刪除最長時間沒有被訪問的值。
【常規解法】
通常用一個雙向連結串列來記錄最長時間沒被訪問的元素,因為雙向連結串列可以在O(1)的時間內實現將某個結點移動到表頭和刪除尾部結點。
上面程式碼中用list實現,其remove時實際上是遍歷整個list來尋找某個結點的。
LeetCode沒有對時間作要求,面試時肯定會被要求的。