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;
    }
};
posted @ 2017-08-15 11:58  LiBaoquan  阅读(572)  评论(0编辑  收藏  举报