zoukankan      html  css  js  c++  java
  • lintcode-24-LFU缓存

    24-LFU缓存

    LFU是一个著名的缓存算法
    实现LFU中的set 和 get

    样例

    capacity = 3

    set(2,2)
    set(1,1)
    get(2)
    >> 2
    get(1)
    >> 1
    get(2)
    >> 2
    set(3,3)
    set(4,4)
    get(3)
    >> -1
    get(2)
    >> 2
    get(1)
    >> 1
    get(4)
    >> 4
    

    思路

    参考http://www.lintcode.com/zh-cn/problem/lfu-cache/
    在本题中,我们必须要统计每一个 key 出现的次数,所以我们用一个哈希表 cache 来记录当前数据 {key, value} 和其出现次数之间的映射,这样还不够,为了方便操作,我们需要把相同频率的 key 都放到一个 lis t中,那么需要另一个哈希表 freq 来建立频率和一个里面所有 key 都是当前频率的 list 之间的映射。

    code

    #include <list>
    #include <unordered_map>
    
    class LFUCache {
    private:
        int capacity, minFreq;
        unordered_map<int, pair<int, int>> cache;
        unordered_map<int, list<int>> freq;
        unordered_map<int, list<int>::iterator> iter;
        
    public:
        // @param capacity, an integer
        LFUCache(int capacity) {
            // Write your code here
            this->capacity = capacity;
        }
    
        // @param key, an integer
        // @param value, an integer
        // @return nothing
        void set(int key, int value) {
            // Write your code here
            if (capacity <= 0) {
                return;
            }
            // key 已存在,更新 Value
            if (get(key) != -1) {
                cache[key].first = value;
                return;
            }
            // cache 已满,擦除 minFreq 的 key
            if (cache.size() >= capacity) {
                cache.erase(freq[minFreq].front());
                iter.erase(freq[minFreq].front());
                freq[minFreq].pop_front();
            }
            // 写入新 key
            cache[key] = { value, 1 };
            freq[1].push_back(key);
            iter[key] = --freq[1].end();
            minFreq = 1;
        }
    
        // @return an integer
        int get(int key) {
            // Write your code here
            // 不存在此 key
            if (cache.count(key) == 0) {
                return -1;
            }
            // 更新 cache
            freq[cache[key].second].erase(iter[key]);
            cache[key].second++;
            freq[cache[key].second].push_back(key);
            iter[key] = --freq[cache[key].second].end();
            if (freq[minFreq].size() == 0) {
                minFreq++;
            }
            return cache[key].first;
        }
    };
    
  • 相关阅读:
    无法往u盘里边复制超过4G的单个文件解决方法
    vue 自定义属性判断点击每个item 显示隐藏
    前端小组分享会之异步回调函数中的上下文
    git 的一些命令
    ES学习之promise
    mac找到占用端口号的进程ID
    meta link
    webpack学习笔记--安装
    css样式之 direction
    日常积累之JSON.stringify和JSON.parse substr
  • 原文地址:https://www.cnblogs.com/libaoquan/p/7364360.html
Copyright © 2011-2022 走看看