Leetcode 146. LRU 緩存機(jī)制

前言

緩存是一種提高數(shù)據(jù)讀取性能的技術(shù)佑笋,在計(jì)算機(jī)中cpu和主內(nèi)存之間讀取數(shù)據(jù)存在差異,CPU和主內(nèi)存之間有CPU緩存印颤,而且在內(nèi)存和硬盤有內(nèi)存緩存请祖。當(dāng)主存容量遠(yuǎn)大于CPU緩存订歪,或磁盤容量遠(yuǎn)大于主存時(shí),哪些數(shù)據(jù)應(yīng)該被應(yīng)該被清理肆捕,哪些數(shù)據(jù)應(yīng)該被保留刷晋,這就需要緩存淘汰策略來決定。常見的策略有三種:先進(jìn)先出策略FIFO(First In,First Out)、最少使用策略LFU(Least Frequently Used)眼虱、最近最少使用策略LRU(Least Recently Used)喻奥。

LRU描述

設(shè)計(jì)和實(shí)現(xiàn)一個(gè) LRU (最近最少使用) 緩存機(jī)制 。
實(shí)現(xiàn) LRUCache 類:

  • LRUCache(int capacity) 以正整數(shù)作為容量 capacity 初始化 LRU 緩存
  • int get(int key) 如果關(guān)鍵字 key 存在于緩存中捏悬,則返回關(guān)鍵字的值撞蚕,否則返回 -1 。
  • void put(int key, int value) 如果關(guān)鍵字已經(jīng)存在过牙,則變更其數(shù)據(jù)值甥厦;如果關(guān)鍵字不存在,則插入該組「關(guān)鍵字-值」寇钉。當(dāng)緩存容量達(dá)到上限時(shí)刀疙,它應(yīng)該在寫入新數(shù)據(jù)之前刪除最久未使用的數(shù)據(jù)值,從而為新的數(shù)據(jù)值留出空間扫倡。

解題思路 哈希表 + 雙向鏈表

  • 針對(duì)LRU的特點(diǎn)谦秧,選擇使用雙鏈表實(shí)現(xiàn)。
  • 使用 gut 方法獲取數(shù)據(jù)撵溃,如果有數(shù)據(jù)疚鲤,把返回?cái)?shù)據(jù),并且把數(shù)據(jù)放在鏈表頭部缘挑。
  • 使用 put 方法存放數(shù)據(jù)集歇,如果數(shù)據(jù)存在,直接覆蓋新值卖哎;如果數(shù)據(jù)不存在鬼悠,添加新值。新值都放在鏈表頭部亏娜。此外,還需要判斷緩存有沒有超出容量 capacity蹬挺,如果有超出维贺,刪除鏈表的尾結(jié)點(diǎn)。
  • 因?yàn)槭菃捂湵戆桶铮看潍@取數(shù)據(jù)溯泣,或者刪除數(shù)據(jù),都需要遍歷一遍鏈表榕茧,時(shí)間復(fù)雜度是O(n),這里使用hash來記錄每個(gè)數(shù)據(jù)的位置垃沦,將數(shù)據(jù)訪問的時(shí)間復(fù)雜度降到O(1)。
class LRUCache {

    class DLinkedNode{
        int key;
        int value;
        DLinkedNode prev;
        DLinkedNode next;

        public DLinkedNode() {}

        public DLinkedNode(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }

    private int size;

    private int capacity;

    private DLinkedNode head;

    private DLinkedNode tail;

    private Map<Integer,DLinkedNode> cache = new HashMap<>();

    public LRUCache(int capacity) {
        this.size = 0;
        this.capacity = capacity;
        head = new DLinkedNode();
        tail = new DLinkedNode();
        head.next = tail;
        tail.prev = head;
    }
    
    public int get(int key) {
        DLinkedNode node = cache.get(key);
        if (node == null) {
            return -1;
        }
        //找到并移動(dòng)到首位
        moveToHead(node);
        return node.value;

    }
    
    public void put(int key, int value) {
        DLinkedNode node = cache.get(key);
        if (node == null) {
            //不存在就創(chuàng)建一個(gè)新的節(jié)點(diǎn)
            DLinkedNode newNode = new DLinkedNode(key,value);
            cache.put(key,newNode);
            addToHead(newNode);
            size++;
            if (size > capacity) {
                //超出容量用押,移除最后節(jié)點(diǎn)
                DLinkedNode tail = removeTail();
                cache.remove(tail.key);
                size--;
            }
        } else {
            //key存在肢簿,覆蓋value,并移到頭部
            if (node.value != value) {
                node.value = value;
            }
            moveToHead(node);

        }
    }

    private DLinkedNode removeTail() {
        DLinkedNode node = tail.prev;
        removeNode(node);
        return node;
    }

    private DLinkedNode removeNode(DLinkedNode node) {
        node.next.prev = node.prev;
        node.prev.next = node.next;
        return node;
    }

    private void moveToHead(DLinkedNode node) {
        removeNode(node);
        addToHead(node);
    }

    private void addToHead(DLinkedNode node) {
        node.prev = head;
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
    }
}

參考

LRU維基百科
極客時(shí)間-王爭(zhēng)-如何實(shí)現(xiàn)LRU緩存淘汰算法?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市池充,隨后出現(xiàn)的幾起案子桩引,更是在濱河造成了極大的恐慌,老刑警劉巖收夸,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坑匠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡卧惜,警方通過查閱死者的電腦和手機(jī)厘灼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咽瓷,“玉大人手幢,你說我怎么就攤上這事〕老辏” “怎么了围来?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)匈睁。 經(jīng)常有香客問我监透,道長(zhǎng),這世上最難降的妖魔是什么航唆? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任胀蛮,我火速辦了婚禮,結(jié)果婚禮上糯钙,老公的妹妹穿的比我還像新娘粪狼。我一直安慰自己,他們只是感情好任岸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布再榄。 她就那樣靜靜地躺著,像睡著了一般享潜。 火紅的嫁衣襯著肌膚如雪困鸥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天剑按,我揣著相機(jī)與錄音疾就,去河邊找鬼。 笑死艺蝴,一個(gè)胖子當(dāng)著我的面吹牛猬腰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播猜敢,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼姑荷,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼盒延!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起厢拭,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤兰英,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后供鸠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畦贸,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年楞捂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了薄坏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡寨闹,死狀恐怖胶坠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情繁堡,我是刑警寧澤沈善,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站椭蹄,受9級(jí)特大地震影響闻牡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜绳矩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一罩润、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翼馆,春花似錦割以、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至珍特,卻和暖如春祝峻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扎筒。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酬姆,地道東北人嗜桌。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像辞色,于是被迫代替她去往敵國(guó)和親骨宠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

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

  • 題目描述:運(yùn)用你所掌握的數(shù)據(jù)結(jié)構(gòu),設(shè)計(jì)和實(shí)現(xiàn)一個(gè) LRU (最近最少使用) 緩存機(jī)制层亿。它應(yīng)該支持以下操作: 獲取...
    簡(jiǎn)單書寫_閱讀 316評(píng)論 0 0
  • 146. LRU緩存機(jī)制 題目來源:力扣(LeetCode)https://leetcode-cn.com/pro...
    大夢(mèng)三千秋閱讀 325評(píng)論 0 2
  • 題目 運(yùn)用你所掌握的數(shù)據(jù)結(jié)構(gòu)桦卒,設(shè)計(jì)和實(shí)現(xiàn)一個(gè) LRU (最近最少使用) 緩存機(jī)制。它應(yīng)該支持以下操作: 獲取數(shù)據(jù)...
    多彩海洋閱讀 272評(píng)論 1 1
  • 運(yùn)用你所掌握的數(shù)據(jù)結(jié)構(gòu)匿又,設(shè)計(jì)和實(shí)現(xiàn)一個(gè) LRU (最近最少使用) 緩存機(jī)制 方灾。實(shí)現(xiàn) LRUCache 類: LR...
    刻苦驢噥閱讀 161評(píng)論 0 0
  • LRU緩存機(jī)制 運(yùn)用你所掌握的數(shù)據(jù)結(jié)構(gòu),設(shè)計(jì)和實(shí)現(xiàn)一個(gè) LRU (最近最少使用) 緩存機(jī)制 碌更。實(shí)現(xiàn) LRUCac...
    一個(gè)酷酷的男子閱讀 55評(píng)論 0 0