色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

設計并實現一個滿足LRU約束的數據結構

冬至子 ? 來源:i余數 ? 作者:i余數 ? 2023-06-07 17:05 ? 次閱讀

題目

請你設計并實現一個滿足 「LRU (最近最少使用) 緩存」 約束的數據結構。

實現 LRUCache 類:

  • LRUCache(int capacity)「正整數」 作為容量 capacity 初始化 LRU 緩存
  • int get(int key) 如果關鍵字 key 存在于緩存中,則返回關鍵字的值,否則返回 -1
  • void put(int key, int value) 如果關鍵字 key 已經存在,則變更其數據值 value ;如果不存在,

則向緩存中插入該組 key-value 。如果插入操作導致關鍵字數量超過 capacity ,則應該 「逐出」 最久未使用的關鍵字。

1.jpg

示例:

輸入
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
輸出
[null, null, null, 1, null, -1, null, -1, 3, 4]

解釋
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 緩存是 {1=1}
lRUCache.put(2, 2); // 緩存是 {1=1, 2=2}
lRUCache.get(1);    // 返回 1
lRUCache.put(3, 3); // 該操作會使得關鍵字 2 作廢,緩存是 {1=1, 3=3}
lRUCache.get(2);    // 返回 -1 (未找到)
lRUCache.put(4, 4); // 該操作會使得關鍵字 1 作廢,緩存是 {4=4, 3=3}
lRUCache.get(1);    // 返回 -1 (未找到)
lRUCache.get(3);    // 返回 3
lRUCache.get(4);    // 返回 4

提示:

1.jpg

題解(哈希表 + 雙向鏈表)

解題之前先了解一下什么是 「LRU緩存」LRU 的英文全稱為 Latest Recently Used,即 「最近最少使用」 。在緩存占滿的時候,先刪除最舊的數據。

1.jpg

Java 代碼實現

class LRUCache {

    private int capacity;

    private Map< Integer, ListNode > cache;

    // 保護節點,protectHead.next 為head節點, protectTail.pre為tail節點
    private ListNode protectHead = new ListNode();
    private ListNode protectTail = new ListNode();

    public LRUCache(int capacity) {
        this.capacity = capacity;
        cache = new HashMap<  >(capacity);
        protectHead.next = protectTail;
        protectTail.pre = protectHead;
    }


    // 刪除指定節點
    private void remove(ListNode listNode){
        listNode.pre.next = listNode.next;
        listNode.next.pre = listNode.pre;

        listNode.pre = null;
        listNode.next = null;
    }

    // 添加到末尾
    private void addToTail(ListNode listNode){

        protectTail.pre.next = listNode;
        listNode.pre = protectTail.pre;

        listNode.next = protectTail;
        protectTail.pre = listNode;
        
    }

    // 從當前位置移動到末尾
    private void moveToTail(ListNode listNode){
        
        this.remove(listNode);
        this.addToTail(listNode);
        
    }
    
    public int get(int key) {
        if(cache.containsKey(key)){
            ListNode listNode = cache.get(key);
            this.moveToTail(listNode);
            return listNode.value;
        }else{
            return -1;
        }

    }
    
    public void put(int key, int value) {
        if(cache.containsKey(key)){
            // 將 key 移動到最新的位置
            // 1. 在舊的位置刪除
            // 2. 追加key到鏈表末尾
            ListNode listNode = cache.get(key);

            // 這里必須重新賦值,雖然緩沖已經存在了,但是可能值不一樣。
            listNode.value = value;
            this.moveToTail(listNode);
            return;

        }

        if(cache.size() == capacity){
            // 1. 找到最舊的數據,也就是鏈表的head,刪除head
            // 2. 在cache map 中刪除 head對應的key
            ListNode headNode = protectHead.next;
            this.remove(headNode);
            cache.remove(headNode.key);
        }


        // 1. 添加新的key到cache map
        // 2. 追加新的key到鏈表末尾

        ListNode listNode = new ListNode();
        listNode.key = key;
        listNode.value = value;

        this.addToTail(listNode);
        cache.put(key, listNode);

    }
}

class ListNode{
    int key;
    int value;
    ListNode pre;
    ListNode next;

}

Go 代碼實現

// 定義雙向鏈表
type MyListNode struct {
    key, value int
    pre, next *MyListNode
}

type LRUCache struct { 
    size, capacity int
    cache map[int]*MyListNode
    protectHead, protectTail *MyListNode
}


func Constructor(capacity int) LRUCache {
    lruCache := LRUCache{
        size: 0,
        capacity: capacity,
        cache: map[int]*MyListNode{},
        protectHead: &MyListNode{},
        protectTail: &MyListNode{},
    }

    lruCache.protectHead.next = lruCache.protectTail
    lruCache.protectTail.pre = lruCache.protectHead
    return lruCache
}


func (this *LRUCache) Get(key int) int {
    if listNode, ok := this.cache[key]; ok {
        this.moveToTail(listNode);
        return listNode.value;
    }else{
        return -1
    }
}


func (this *LRUCache) Put(key int, value int)  {
    if listNode, ok := this.cache[key]; ok {
        listNode.value = value;
        this.moveToTail(listNode);
        return;
    }
    if(this.size == this.capacity){
        headNode := this.protectHead.next;
        this.remove(headNode);
        delete(this.cache, headNode.key);
        this.size--
    }

    listNode := &MyListNode{
        key: key,
        value: value,
    }


    this.addToTail(listNode)
    this.cache[key] = listNode
    this.size++
}

// 刪除指定節點
func (this *LRUCache) remove(listNode *MyListNode){
    listNode.pre.next = listNode.next;
    listNode.next.pre = listNode.pre;

    listNode.pre = nil;
    listNode.next = nil;
}


// 添加到末尾
func (this *LRUCache) addToTail(listNode *MyListNode){
    this.protectTail.pre.next = listNode
    listNode.pre = this.protectTail.pre

    listNode.next = this.protectTail
    this.protectTail.pre = listNode
}


// 從當前位置移動到末尾
func (this *LRUCache) moveToTail(listNode *MyListNode){
    this.remove(listNode);
    this.addToTail(listNode);
}

復雜度分析

1.jpg

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    19

    文章

    2971

    瀏覽量

    104854
  • cache技術
    +關注

    關注

    0

    文章

    41

    瀏覽量

    1069
收藏 人收藏

    評論

    相關推薦

    什么是數據結構(Data Structrue)

    一個一個元素數據對象:具有相同特性的數據元素的集合結構數據元素之間具有的關系(聯系) 二. 
    發表于 02-09 17:17

    GPIB命令的數據結構

    GPIB命令結點;考慮程序實現的效率問題以及管理維護方面的因素,對普通的樹進行改造,從而形成特有的"GPIB命令樹"。【關鍵詞】:通用接口總線(GPIB);;數據結構;;樹
    發表于 04-24 09:44

    【原創】Android開發—Lru核心數據結構實現突破緩存框架

    【原創】Android開發—Lru核心數據結構實現突破緩存框架回復即可獲取下載鏈接[hide=d15]鏈接:http://pan.baidu.com/s/1c2BfjsW 密碼:bta5 更多學習資料加Q:1352716312,
    發表于 06-21 16:58

    數據結構

    數據的邏輯結構分為線性結構和非線性結構非空的線性結構
    發表于 03-04 14:13

    常見的數據結構

    順序表結構的底層實現借助的就是數組,因此對于初學者來說,可以把順序表完全等價為數組,但實則不是這樣。數據結構是研究數據存儲方式的門學科,它
    發表于 05-10 07:58

    GPIB命令的數據結構

    針對GPIB命令的結構,提出種存儲GPIB命令的數據結構。根據GPIB命令的層次關系的特點,選擇數據結構中“樹”的概念來存儲GPIB命令結點;
    發表于 02-10 16:20 ?70次下載

    GPIB命令的數據結構

    針對GPIB命令的結構,提出種存儲GPIB命令的數據結構。根據GPIB命令的層次關系的特點,選擇數據結構中“樹”的概念來存儲GPIB命令結點;
    發表于 01-04 10:13 ?0次下載

    數據結構是什么_數據結構有什么用

    數據結構是計算機存儲、組織數據的方式。數據結構是指相互之間存在種或多種特定關系的數據元素的集合。通常情況下,精心選擇的
    發表于 11-17 14:45 ?1.6w次閱讀
    <b class='flag-5'>數據結構</b>是什么_<b class='flag-5'>數據結構</b>有什么用

    什么是數據結構?為什么要學習數據結構數據結構的應用實例分析

    本文檔的主要內容詳細介紹的是什么是數據結構?為什么要學習數據結構數據結構的應用實例分析包括了:數據結構在串口通信當中的應用,數據結構在按鍵
    發表于 09-26 15:45 ?14次下載
    什么是<b class='flag-5'>數據結構</b>?為什么要學習<b class='flag-5'>數據結構</b>?<b class='flag-5'>數據結構</b>的應用實例分析

    如何解決數據結構設計最大頻率棧問題?

    。 力扣第 895 題要求我們實現特殊的數據結構「最大頻率棧」,比較有意思,讓我們實現下面這兩
    的頭像 發表于 03-02 11:02 ?1437次閱讀

    數據結構解決滑動窗口問題

    前文用 [單調棧解決三道算法問題]介紹了單調棧這種特殊數據結構,本文寫類似的數據結構「單調隊列」。 也許這種數據結構的名字你沒聽過,其
    的頭像 發表于 04-19 10:50 ?665次閱讀
    <b class='flag-5'>數據結構</b>解決滑動窗口問題

    如何理解掌握Java數據結構

    Java 數據結構是 Java 程序員必須掌握的重要知識之
    的頭像 發表于 06-06 15:53 ?839次閱讀

    NetApp的數據結構是如何演變的

    一數據跨分布式資源進行管理,以實現數據移動的致性和控制,安全、可見性、保護和訪問。 本文定義了數據結構及其體系
    發表于 08-25 17:15 ?0次下載
    NetApp的<b class='flag-5'>數據結構</b>是如何演變的

    epoll的基礎數據結構

    先看下 eventpoll 這個數據結構,這個數據結構是我們在調用 epoll_create 之后內核創建的句柄,表示了
    的頭像 發表于 11-10 10:20 ?816次閱讀
    epoll的基礎<b class='flag-5'>數據結構</b>

    redis數據結構的底層實現

    Redis是種內存鍵值數據庫,常用于緩存、消息隊列、實時數據分析等場景。它的高性能得益于其精心設計的數據結構和底層實現。本文將詳細介紹Re
    的頭像 發表于 12-05 10:14 ?629次閱讀
    主站蜘蛛池模板: 免费特黄一区二区三区视频一| 色欲AV亚洲永久无码精品麻豆 | 诱咪视频免费| 久久影院一区| s8sp视频高清在线播放| 微福利92合集| 葵司中文第一次大战黑人| FREE乌克兰嫩交HD| 日韩在线视频www色| 极品色αv影院| x69老师x日本| 亚洲午夜无码久久久久蜜臀av| 欧美gv明星| 狠狠色狠狠色综合| 插骚妇好爽好骚| 一本色道久久综合亚洲精品蜜桃冫 | 91精品视频网站| 十分钟免费看完整视频| 久久婷婷色一区二区三区| 福利一区国产| 最近在线视频观看2018免费| 四房播播开心五月| 猫咪最新破解版下载| 国产精品青青在线麻豆| 91亚洲精品福利在线播放| 亚洲2017天堂色无码| 你是淫荡的我的女王| 国产做国产爱免费视频| chinese东北夫妻video| 亚洲综合视频| 射90黑b丝女| 免费国产网站| 国产在线精品视频二区| 拔擦拔擦8X永久华人免费播放器| 亚洲伊人成综合人影院| 熟女少妇内射日韩亚洲| 欧美成人一区二免费视频| 精品少妇高潮蜜臀涩涩AV| 国产精品久AAAAA片| mdapptv麻豆下载| 88福利视频|