实战:实现一个LRU

简介: 实战:实现一个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);
 */
#include <bits/stdc++.h>
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();
        }
    }
};

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

相关文章
|
人工智能 NoSQL Redis
Collaborative Gym:斯坦福人机协作框架开源!异步交互+三方感知,让你的AI学会主动补位
介绍Collaborative Gym,一个专注于人机协作的框架,支持异步交互和多种任务环境。
534 14
Collaborative Gym:斯坦福人机协作框架开源!异步交互+三方感知,让你的AI学会主动补位
|
机器学习/深度学习 人工智能 自然语言处理
商汤自研的通用Embedding模型Piccolo2
【6月更文挑战第19天】商汤Piccolo2模型**是其新推出的通用Embedding技术,通过多任务混合损失训练提升泛化能力,在CMTEB基准测试中刷新纪录。模型动态调整向量维度与使用MRL方法增强语义理解,但可能增加计算成本,且有观点认为其改进非革命性。[论文链接](https://arxiv.org/abs/2405.06932)
650 1
|
存储 Serverless API
Serverless 架构实现弹幕场景问题之在initializer方法中初始化数据库实例如何解决
Serverless 架构实现弹幕场景问题之在initializer方法中初始化数据库实例如何解决
388 0
|
存储 API 虚拟化
VMware产品问题之整合其产品以提供统一的产品门户体验如何解决
VMware产品问题之整合其产品以提供统一的产品门户体验如何解决
143 0
|
程序员 Python
Python列表批量删除所有指定元素的函数设计
使用Python删除列表中所有指定元素的方法可能有很多种,比如for循环之类的,但这里要设计一种可以直接通过函数传参的形式输入要删除的指定元素的方法,而且尽可能地让Python的代码足够简单的同时,能够重复利用,且方便重复利用,因此,
167 4
|
Python
Python 计算器程序
下面是一个简单的 Python 计算器程序,可以实现基本的加减乘除运算:
305 3
|
存储 传感器 运维
AloT 企业物联网平台入门01|学习笔记(一)
快速学习 AloT 企业物联网平台入门01
1092 17
AloT 企业物联网平台入门01|学习笔记(一)
|
存储 容灾 Linux
UOS统一操作系统,让我们拥抱中文操作系统,打造属于自己的私人企业级网盘
UOS统一操作系统,让我们拥抱中文操作系统,打造属于自己的私人企业级网盘
980 0
UOS统一操作系统,让我们拥抱中文操作系统,打造属于自己的私人企业级网盘
|
存储 负载均衡 算法
【系统架构】分布式系统架构设计
【系统架构】分布式系统架构设计
1147 0
|
前端开发 JavaScript
css内凹圆角
border-radius 属性是一个简写属性,用于设置四个 border-*-radius 属性。4个角(顺时针方向,左上,右上,右下,左下),每个角都有两个半径,水平半径和垂直半径,
759 0
css内凹圆角