设计LRU/LFU缓存结构

文章介绍了LRU和LFU两种缓存淘汰策略的实现,主要利用双向链表和哈希表数据结构。LRU通过维护最近使用的键值对在链表头部,而LFU则是根据操作频率组织数据,相同频率的节点位于同一链表。当缓存满时,LRU删除最近最少使用的项,LFU则考虑操作频率,优先保留高频操作的项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LRU缓存结构

题目描述

思路

采用双向链表存储所有键值对,最近操作的键值对在链表头部。为了提高set和get的效率,采用从key映射到对应迭代器的哈希表

核心代码

class Solution {
public:
    int cap;
    list<pair<int,int>> dlist;
    unordered_map<int,list<pair<int,int>>::iterator> hash;

    Solution(int capacity){
        cap=capacity;
    }
    
    int get(int key) {
        if(!hash.count(key)) return -1;
        //if(hash.find(key)==hash.end()) return -1;
        auto temp=*hash[key];
        dlist.erase(hash[key]);
        dlist.push_front(temp);
        hash[key]=dlist.begin();
        return dlist.front().second;
    }
    
    void set(int key, int value){
        if(hash.count(key)){
            dlist.erase(hash[key]);
        }
        else if(cap==dlist.size()){
            auto temp=dlist.back();
            dlist.pop_back();
            hash.erase(temp.first);
        }
        dlist.push_front(pair<int,int>{key,value});
        hash[key]=dlist.begin();
    }
};

LFU缓存结构

题目描述

思路

操作次数相同的节点放在一条链表中,最近操作的节点插入在头端,每个节点为一个vector,其中依次存有操作次数,键,值。

增加一个由操作频率映射到双向链表的哈希表,并采用全局变量min_freq存当前最新操作次数,size存剩余容量。

核心代码

class Solution {
public:
    /**
     * lfu design
     * @param operators int整型vector<vector<>> ops
     * @param k int整型 the k
     * @return int整型vector
     */
    unordered_map<int,list<vector<int>>> freq_mp;
    unordered_map<int,list<vector<int>>::iterator> mp;
    int size=0;
    int min_freq=0;
    vector<int> LFU(vector<vector<int> >& operators, int k) {
        vector<int> res;
        size=k;
        int n=operators.size();
        for(int i=0;i<n;++i){
            if(operators[i][0]==1){
                set(operators[i][1],operators[i][2]);
            }
            else{
                res.push_back(get(operators[i][1]));
            }
        }
        return res;
    }
    int get(int key){
        if(mp.find(key)==mp.end()) return -1;
        auto iter=mp[key];
        int res=(*iter)[2];
        update(iter,key,res);
        return res;
    }
    void update(list<vector<int>>::iterator iter,int key,int value){
        int freq=(*iter)[0];
        freq_mp[freq].erase(iter);
        if(freq_mp[freq].empty()){
            freq_mp.erase(freq);
            if(freq==min_freq) ++min_freq;
        }
        freq_mp[freq+1].push_front({freq+1,key,value});
        mp[key]=freq_mp[freq+1].begin();
    }
    void set(int key,int value){
        if(mp.find(key)!=mp.end()){
            update(mp[key],key,value);
            return;
        }
        if(!size){
            int del_key=freq_mp[min_freq].back()[1];
            freq_mp[min_freq].pop_back();
            if(freq_mp[min_freq].empty()){
                freq_mp.erase(min_freq);
            }
            mp.erase(del_key);
        }
        else{
            --size;
        }
        min_freq=1;
        freq_mp[1].push_front({1,key,value});
        mp[key]=freq_mp[1].begin();
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值