146. LRU Cache LRU緩存機制

題目鏈接

tag:

  • Hard;

question:
??Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.

  • get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
  • put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

The cache is initialized with a positive capacity.

Follow up:
Could you do both operations in O(1) time complexity?

Example:

LRUCache cache = new LRUCache( 2 /* capacity */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // returns 1
cache.put(3, 3); // evicts key 2
cache.get(2); // returns -1 (not found)
cache.put(4, 4); // evicts key 1
cache.get(1); // returns -1 (not found)
cache.get(3); // returns 3
cache.get(4); // returns 4</pre>

思路:
??這道題讓我們實現(xiàn)一個LRU緩存器,LRU是Least Recently Used的簡寫朵你,就是最近最少使用的意思各聘。那么這個緩存器主要有兩個成員函數(shù),get和put抡医,其中get函數(shù)是通過輸入key來獲得value躲因,如果成功獲得后,這對(key, value)升至緩存器中最常用的位置(頂部)忌傻,如果key不存在大脉,則返回-1。而put函數(shù)是插入一對新的(key, value)水孩,如果原緩存器中有該key镰矿,則需要先刪除掉原有的,將新的插入到緩存器的頂部俘种。如果不存在秤标,則直接插入到頂部。若加入新的值后緩存器超過了容量宙刘,則需要刪掉一個最不常用的值苍姜,也就是底部的值。具體實現(xiàn)時我們需要三個私有變量悬包,cap, l和m衙猪,其中cap是緩存器的容量大小,l是保存緩存器內(nèi)容的列表布近,m是HashMap垫释,保存關鍵值key和緩存器各項的迭代器之間映射,方便我們以O(1)的時間內(nèi)找到目標項撑瞧。

??然后我們再來看get和put如何實現(xiàn)棵譬,get相對簡單些,我們在HashMap中查找給定的key季蚂,若不存在直接返回-1茫船。如果存在則將此項移到頂部,這里我們使用C++ STL中的函數(shù) splice 扭屁,專門移動鏈表中的一個或若干個結(jié)點到某個特定的位置算谈,這里我們就只移動key對應的迭代器到列表的開頭,然后返回value料滥。這里再解釋一下為啥HashMap不用更新然眼,因為HashMap的建立的是關鍵值key和緩存列表中的迭代器之間的映射,get函數(shù)是查詢函數(shù)葵腹,如果關鍵值key不在HashMap高每,那么不需要更新屿岂。如果在,我們需要更新的是該key-value鍵值對兒對在緩存列表中的位置鲸匿,而HashMap中還是這個key跟鍵值對兒的迭代器之間的映射爷怀,并不需要更新什么。

??對于put带欢,我們也是現(xiàn)在HashMap中查找給定的key运授,如果存在就刪掉原有項,并在頂部插入新來項乔煞,然后判斷是否溢出吁朦,若溢出則刪掉底部項(最不常用項)。代碼如下:

class LRUCache{
public:
    LRUCache(int capacity) {
        cap = capacity;
    }
    
    int get(int key) {
        auto it = m.find(key);
        if (it == m.end()) 
            return -1;
        l.splice(l.begin(), l, it->second);
        return it->second->second;
    }
    
    void put(int key, int value) {
        auto it = m.find(key);
        if (it != m.end()) 
            l.erase(it->second);
        l.push_front(make_pair(key, value));
        m[key] = l.begin();
        if (m.size() > cap) {
            int k = l.rbegin()->first;
            l.pop_back();
            m.erase(k);
        }
    }
    
private:
    int cap;
    list<pair<int, int>> l;
    unordered_map<int, list<pair<int, int>>::iterator> m;
};
/**
 * 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);
 */

轉(zhuǎn)自:https://www.cnblogs.com/grandyang/p/4587511.html

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末渡贾,一起剝皮案震驚了整個濱河市逗宜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌空骚,老刑警劉巖纺讲,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異囤屹,居然都是意外死亡刻诊,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門牺丙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人复局,你說我怎么就攤上這事冲簿。” “怎么了亿昏?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵峦剔,是天一觀的道長。 經(jīng)常有香客問我角钩,道長吝沫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任递礼,我火速辦了婚禮惨险,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘脊髓。我一直安慰自己辫愉,他們只是感情好,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布将硝。 她就那樣靜靜地躺著恭朗,像睡著了一般屏镊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上痰腮,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天而芥,我揣著相機與錄音,去河邊找鬼膀值。 笑死棍丐,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的虫腋。 我是一名探鬼主播骄酗,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼悦冀!你這毒婦竟也來了趋翻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤盒蟆,失蹤者是張志新(化名)和其女友劉穎踏烙,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體历等,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡讨惩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了寒屯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荐捻。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖寡夹,靈堂內(nèi)的尸體忽然破棺而出处面,到底是詐尸還是另有隱情,我是刑警寧澤菩掏,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布魂角,位于F島的核電站,受9級特大地震影響智绸,放射性物質(zhì)發(fā)生泄漏野揪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一瞧栗、第九天 我趴在偏房一處隱蔽的房頂上張望斯稳。 院中可真熱鬧,春花似錦迹恐、人聲如沸平挑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽通熄。三九已至唆涝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間唇辨,已是汗流浹背廊酣。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赏枚,地道東北人亡驰。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像饿幅,于是被迫代替她去往敵國和親凡辱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容