码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 实战:实现一个LRU


    实战:实现一个LRU

    • Cache
    • LRU cache
    • 实战:实现一个LRU

    Cache

    缓存的两个要素: 大小、替换策略

    常见替换算法:

    • LRU - least recently used,最近最少使用( 淘汰最旧数据)
    • LFU- least frequently used,最不经常使用(淘汰频次最少数据)

    LRU cache

    在这里插入图片描述

    实战:实现一个LRU

    146. LRU缓存

    https://leetcode.cn/problems/lru-cache/

    哈希表+双向链表

    • 双向链表用于按时间顺序保存数据
    • 哈希表用于把key映射到链表结点(指针/引用)

    0(1)访问:直接检查哈希表
    0(1)更新:通过哈希表定位到链表结点,删除该结点(若存在) ,在表头重新插入
    0(1)删除:总是淘汰链表末尾结点,同时在哈希表中删除

    class LRUCache {
    public:
        LRUCache(int capacity) {
            this->capacity = capacity;
            head = new Node();
            tail = new Node();
            size = 0;
            head->next = tail;
            tail->pre = head;
        }
        
        int get(int key) {
            if(h.find(key) == h.end()){
                return -1;
            }
            Node* node = h[key];
            remove(node);
            insert(head,node);
            return node->value;
        }
        
        void put(int key, int value) {
            if(h.find(key) == h.end()){
                Node* node = new Node();
                node->key = key;
                node->value = value;
                h[key] = node;
                insert(head,node);
                
                
                if(h.size() > capacity){
                    h.erase(tail->pre->key);
                    remove(tail->pre);
                    
                }
    
               
            }else{
                Node* node = h[key];
                node->value = value;
                remove(node);
                insert(head,node);
            }
        }
    
    private:
        struct Node {
            int key;
            int value;
            Node* pre;
            Node* next;
        };
        unordered_map<int,Node*> h;
        Node* head;
        Node* tail;
        int size;
        int capacity;
    
        void insert(Node* p,Node* node){
            node->next = p->next;     
            node->pre = p;
            p->next->pre = node;
            p->next = node;
        }
    
        void remove(Node* node){
            node->pre->next = node->next;
            node->next->pre = node->pre;
        }
    
    };
    
    /**
     * 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);
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    #include 
    
    using namespace std;
    
    class LRUCache
    {
        unordered_map<int, list<pair<int, int>>::iterator> hash;
        list<pair<int, int>> cache;
        int size;
    
    public:
        LRUCache(int capacity) : size(capacity) {}
        int get(int key)
        {
            auto it = hash.find(key);
            if (it == hash.end())
            {
                return -1;
            }
            cache.splice(cache.begin(), cache, it->second);
            return it->second->second;
        }
        void put(int key, int value)
        {
            auto it = hash.find(key);
            if (it != hash.end())
            {
                it->second->second = value;
                return cache.splice(cache.begin(), cache, it->second);
            }
            cache.insert(cache.begin(), make_pair(key, value));
            hash[key] = cache.begin();
            if (cache.size() > size)
            {
                hash.erase(cache.back().first);
                cache.pop_back();
            }
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

  • 相关阅读:
    uinapp微信小程序隐私政策授权
    006-JavaSE基础巩固练习:while循环结构的练习
    springboot基于Web的社区医院管理服务系统springboot025
    GMT安装与使用
    History库源码分析-Action 动作类型
    SpringBoot——静态资源及原理
    CSDN21天学习挑战赛之折半插入排序
    代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
    【Linux系统管理】10 Shell 编程进阶篇
    Nginx快速入门
  • 原文地址:https://blog.csdn.net/qq_46118239/article/details/126512345
  • 最新文章
  • 【JVM】编译执行与解释执行的区别是什么?JVM 使用哪种方式?
    用 Hashids 优雅解决 C 端自增 ID 暴露问题
    V8引擎 精品漫游指南--Ignition篇(上) 指令 栈帧 槽位 调用约定 内存布局 基础内容
    LLVM Pass快速入门(四):代码插桩
    milkup:桌面端 markdown AI续写和即时渲染
    基于项目工程构建SBOM(软件物料清单)的研究
    鸿蒙应用开发UI基础第二节:鸿蒙应用程序框架核心解析与实操
    .NET 中如何快速实现 List 集合去重?
    扣子Coze实战:从0到1打造抖音+小红书热点监控智能体
    浅谈数据访问层
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号