国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

LRU Cache

Shihira / 340人閱讀

摘要:因?yàn)槭撬袃蓚€(gè)操作的時(shí)間復(fù)雜度都必須是。因?yàn)槭褂镁€(xiàn)性的數(shù)據(jù)結(jié)構(gòu),并且表示操作的先后順序,這樣的結(jié)構(gòu)就是鏈表。我們發(fā)現(xiàn),無(wú)論是還是都有兩個(gè)簡(jiǎn)單操作組成,從鏈表中移除,放到鏈表頭部。如果從尾部移除,將不會(huì)指向任何點(diǎn)。

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) - 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.

這題需要我們?cè)O(shè)計(jì)一個(gè)cache, 有g(shù)et和set兩個(gè)操作。因?yàn)槭莄ache, 所有兩個(gè)操作的時(shí)間復(fù)雜度都必須是O(1)。
get(key) -- O(1) 很明顯,我們需要用一個(gè)hashmap來(lái)實(shí)現(xiàn)O(1)的操作。
set(key, value) -- O(1) 這里有兩種情況,key沒(méi)出現(xiàn)過(guò),就直接加在head。這里出現(xiàn)一個(gè)關(guān)鍵詞head。
因?yàn)槭褂镁€(xiàn)性的數(shù)據(jù)結(jié)構(gòu),并且表示操作的先后順序,這樣的結(jié)構(gòu)就是鏈表。是單鏈表還是雙鏈表?下面我們模擬一下:
capacity = 3
set(1, 100)
set(2, 200)
set(3, 300)
get(2)
如果是單鏈表,簡(jiǎn)單表示如下:
1 -> 2 -> 3 -> null
我們可以得到2并放在頭部。但是這里用的單鏈表,我們無(wú)法知道2的前面是什么,2前面的所有點(diǎn)都會(huì)脫離整體。所以需要一個(gè)雙鏈表。
1 <=> 3 <=> 2 <=> null
我們繼續(xù)操作,set(4, 400),發(fā)現(xiàn)已經(jīng)達(dá)到LRU的容量,需要移除,這時(shí)候發(fā)現(xiàn)我們需要一個(gè)尾部來(lái)告訴我們需要移除哪個(gè)點(diǎn)。
我們發(fā)現(xiàn),無(wú)論是get(key)還是set(key, value)都有兩個(gè)簡(jiǎn)單操作組成,從鏈表中移除,放到鏈表頭部。
可以定義兩個(gè)helper function: remove(node), setHead(node)。

代碼如下,帶注釋?zhuān)?/p>

public class LRUCache {
    class Node{
        int key;
        int value;
        Node pre;       // point to tail direction
        Node next;      // point to head direction
        public Node(int key, int value){
            this.key = key;
            this.value = value;
        }
    }
    
    int capacity;
    Map map = new HashMap<>();
    Node tail = null;
    Node head = null;
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
    }
    
    public int get(int key) {
        if(map.containsKey(key)){       // remove from LRU and put it to head of LRU
            Node n = map.get(key);
            remove(n);
            setHead(n);
            return n.value;
        }
        return -1;
    }
    
    public void set(int key, int value) {
        if(map.containsKey(key)){           // change node value, remove from LRU and put it to head of LRU
            Node old = map.get(key);
            old.value = value;
            remove(old);
            setHead(old);
        } else {
            Node newNode = new Node(key, value);
            if(capacity == map.size()){     //  remove the tail
                map.remove(tail.key);
                remove(tail);
            }
            setHead(newNode);               // set newNode to head
            map.put(key, newNode);
        }
    }
    
    public void remove(Node n){
        if(n.pre != null) {         // change pre node connection
            n.pre.next = n.next;
        } else {                    // check if it is the tail
            tail = n.next;
        }
        
        if(n.next != null) {        // change next node connection
            n.next.pre = n.pre;
        } else {                    // check if it is the head
            head = n.pre;
        }
    }
    
    public void setHead(Node n){
        n.pre = head;
        n.next = null;
        
        if(head != null) {  // check head exist or Not ?
            head.next = n;
        }
        
        head = n;
        if(tail == null){    // empty LRU, intitailize tail node
            tail = head;
        }
    }
}

使用dummyEnd 和dummyHead可以簡(jiǎn)化代碼。

public class LRUCache {
    
    int capacity;
    Map map;
    Node dummyEnd;
    Node dummyHead;
    int count;
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.count = 0;
        map = new HashMap();
        dummyEnd = new Node(0,0);
        dummyHead = new Node(0,0);
        dummyEnd.next = dummyHead;
        dummyHead.pre = dummyEnd;
    }
    
    public int get(int key) {
        Node node = map.get(key);
        if(node == null) {
            return -1;
        } else {
            remove(node);
            putToHead(node);
            return node.val;
        }
    }
    
    public void put(int key, int value) {
        Node oldNode = map.get(key);
        if(oldNode == null) {
            ++count;
            Node newNode = new Node(key, value);
            map.put(key, newNode);
            putToHead(newNode);
            
            if(count > capacity){
                // 從LRU移除
                // 第一次在這里debug了好久,要先取出nextNode, 不然map里remove的就是錯(cuò)誤的點(diǎn),即dummy.next.next。
                Node nextNode = dummyEnd.next;
                remove(nextNode);
                // 從map移除
                map.remove(nextNode.key);
                --count;
            }
            
        } else {
            // 改變值,先移除,再放入頭部
            oldNode.val = value;
            remove(oldNode);
            putToHead(oldNode);
        }
    }
    
    public void putToHead(Node node){
        // 加到頭和前一個(gè)點(diǎn)的中間
        Node preNode = dummyHead.pre;
        preNode.next = node;
        node.pre = preNode;
        dummyHead.pre = node;
        node.next = dummyHead;
    }
    
    public void remove(Node node){
        // 移除。
        node.next.pre = node.pre;
        node.pre.next = node.next;
        // node 如果從尾部移除,將不會(huì)指向任何點(diǎn)。
        node.pre = null;
        node.next = null;
    }
    
    class Node{
        int key, val;
        Node pre, next;
        public Node(int key, int val){
            this.key = key;
            this.val = val;
        }
    }
}

/**
 * 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);
 */

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/66402.html

相關(guān)文章

  • NPM酷庫(kù):lru-cache 基于內(nèi)存的緩存管理

    摘要:酷庫(kù),每天兩分鐘,了解一個(gè)流行庫(kù)。而直接將數(shù)據(jù)保存在程序變量中,最經(jīng)濟(jì)快捷。但是這樣就會(huì)帶來(lái)一些其他問(wèn)題,比如緩存更新緩存過(guò)期等。用于在內(nèi)存中管理緩存數(shù)據(jù),并且支持算法。可以讓程序不依賴(lài)任何外部數(shù)據(jù)庫(kù)實(shí)現(xiàn)緩存管理。 NPM酷庫(kù),每天兩分鐘,了解一個(gè)流行NPM庫(kù)。 為了優(yōu)化程序性能,我們常常需要獎(jiǎng)數(shù)據(jù)緩存起來(lái),根據(jù)實(shí)際情況,我們可以將數(shù)據(jù)存儲(chǔ)到磁盤(pán)、數(shù)據(jù)庫(kù)、redis等。 但是有時(shí)候要緩...

    Yumenokanata 評(píng)論0 收藏0
  • NPM酷庫(kù):lru-cache 基于內(nèi)存的緩存管理

    摘要:酷庫(kù),每天兩分鐘,了解一個(gè)流行庫(kù)。而直接將數(shù)據(jù)保存在程序變量中,最經(jīng)濟(jì)快捷。但是這樣就會(huì)帶來(lái)一些其他問(wèn)題,比如緩存更新緩存過(guò)期等。用于在內(nèi)存中管理緩存數(shù)據(jù),并且支持算法。可以讓程序不依賴(lài)任何外部數(shù)據(jù)庫(kù)實(shí)現(xiàn)緩存管理。 NPM酷庫(kù),每天兩分鐘,了解一個(gè)流行NPM庫(kù)。 為了優(yōu)化程序性能,我們常常需要獎(jiǎng)數(shù)據(jù)緩存起來(lái),根據(jù)實(shí)際情況,我們可以將數(shù)據(jù)存儲(chǔ)到磁盤(pán)、數(shù)據(jù)庫(kù)、redis等。 但是有時(shí)候要緩...

    LoftySoul 評(píng)論0 收藏0
  • 一個(gè)線(xiàn)程安全的 lrucache 實(shí)現(xiàn) --- 讀 leveldb 源碼

    摘要:在閱讀的源代碼的時(shí)候,發(fā)現(xiàn)其中的類(lèi)正是一個(gè)線(xiàn)程安全的實(shí)現(xiàn),代碼非常優(yōu)雅。至此一個(gè)線(xiàn)程安全的類(lèi)就已經(jīng)全部實(shí)現(xiàn),在中使用的緩存是,其實(shí)就是聚合多個(gè)實(shí)例,真正的邏輯都在類(lèi)中。 緩存是計(jì)算機(jī)的每一個(gè)層次中都是一個(gè)非常重要的概念,緩存的存在可以大大提高軟件的運(yùn)行速度。Least Recently Used(lru) cache 即最近最久未使用的緩存,多見(jiàn)與頁(yè)面置換算法,lru 緩存算法在緩存的...

    widuu 評(píng)論0 收藏0
  • 劍指offer/LeetCode146/LintCode134_LRU緩存實(shí)現(xiàn)

    摘要:劍指緩存實(shí)現(xiàn)聲明文章均為本人技術(shù)筆記,轉(zhuǎn)載請(qǐng)注明出處解題思路緩存兩種功能獲取的對(duì)應(yīng),不存在返回版本版本設(shè)置緩存已滿(mǎn),刪除最近最久未被使用的節(jié)點(diǎn),添加新節(jié)點(diǎn)進(jìn)緩存緩存未滿(mǎn),節(jié)點(diǎn)存在,修改節(jié)點(diǎn)不存在,添加新節(jié)點(diǎn)進(jìn)緩存解題思路由于緩存插入和刪除 劍指offer/LeetCode146/LintCode134_LRU緩存實(shí)現(xiàn) 聲明 文章均為本人技術(shù)筆記,轉(zhuǎn)載請(qǐng)注明出處[1] https://s...

    you_De 評(píng)論0 收藏0
  • go實(shí)現(xiàn)LRU cache

    摘要:簡(jiǎn)介概述緩存資源通常比較昂貴通常數(shù)據(jù)量較大時(shí)會(huì)竟可能從較少的緩存滿(mǎn)足盡可能多訪(fǎng)問(wèn)這里有一種假設(shè)通常最近被訪(fǎng)問(wèn)的數(shù)據(jù)那么它就有可能會(huì)被后續(xù)繼續(xù)訪(fǎng)問(wèn)基于這種假設(shè)將所有的數(shù)據(jù)按訪(fǎng)問(wèn)時(shí)間進(jìn)行排序并按驅(qū)逐出舊數(shù)據(jù)那么存在緩存的數(shù)據(jù)就為熱點(diǎn)數(shù)據(jù)這樣既節(jié) 1. LRU簡(jiǎn)介 1.1 概述 緩存資源通常比較昂貴,通常數(shù)據(jù)量較大時(shí),會(huì)竟可能從較少的緩存滿(mǎn)足盡可能多訪(fǎng)問(wèn),這里有一種假設(shè),通常最近被訪(fǎng)問(wèn)的數(shù)據(jù)...

    Jackwoo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

Shihira

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<