题解 | #设计LFU缓存结构#

设计LFU缓存结构

https://www.nowcoder.com/practice/93aacb4a887b46d897b00823f30bfea1

解题思路:使用双哈希表 set + map

使用map存储key和其所有的信息node,包括key值、频率、值、最近使用时间点

使用set从小到大存储node,node根据频率和时间点进行排序,频率不相等则根据频率大小进行排序,频率相等则根据时间大小进行排序,时间大的说明使用时间更近。

#include <climits>
#include <deque>
#include <unordered_map>
#include <vector>
struct Node{
    int keys,vals,fres,times;
    Node(int a,int b,int c,int d):keys(a),vals(b),fres(c),times(d){}
    //重载<运算符,以便根据频率和使用时间点,从小到大存于set中
    bool operator<(const Node & rhs) const
    {
        //如果频率相等,则返回时间小的,否则返回频率小的
        return fres == rhs.fres? times < rhs.times : fres < rhs.fres;
    }

};
class Solution {
public:
    /**
     * lfu design
     * @param operators int整型vector<vector<>> ops
     * @param k int整型 the k
     * @return int整型vector
     */
    int get(int key)
    {
        //排除异常
        if(maxsize == 0)
            return -1;
        auto iter = m.find(key);
        //如果没有这个key值,则返回-1
        if(iter == m.end())
            return -1;
        //取出当前键值
        Node temp = iter->second;
        s.erase(temp);//在set中删除
        temp.fres += 1;//频率+1
        temp.times = ++time;//更新使用的时间点
        iter->second = temp;//存回更新后的值
        s.insert(temp);//存回更新后的值
        return temp.vals;
    }
    void put(int key,int value)
    {
        //排除异常
        if(maxsize == 0)
            return;
        auto iter = m.find(key);
        //如果没有该键值
        if(iter == m.end())
        {
            //如果等于最大长度,则要删除set的第一个元素,这个元素是符合题意的
            if(m.size() == maxsize)
            {
                m.erase(s.begin()->keys);
                s.erase(s.begin());
            }
            //存入新的结点,频率初始为1,时间为当前时间点
            Node temp = Node(key,value,1,++time);
            m.insert({key, temp});
            s.insert(temp);
        }
        //如果有该键值,则更新该键值,类似get
        else 
        {
            //取出当前键值
            Node temp = iter->second;
            s.erase(temp);//在set中删除
            temp.fres += 1;//频率+1
            temp.times = ++time;//更新使用的时间点
            temp.vals = value;//更新value
            iter->second = temp;//存回更新后的值
            s.insert(temp);//存回更新后的值
        }
    }


    vector<int> LFU(vector<vector<int> >& operators, int k) {
        // write code here
        vector<int> res;
        maxsize = k;
        time = 0;
        for(auto x: operators)
        {
            if(x[0] == 1)
                put(x[1],x[2]);
            else
                res.push_back(get(x[1]));
        }
        return res;
    }

private:
    int maxsize,time;
    unordered_map<int, Node> m;
    set<Node> s;
};

全部评论

相关推荐

不愿透露姓名的神秘牛友
11-27 10:52
点赞 评论 收藏
分享
牛舌:如果我不想去,不管对方给了多少,我一般都会说你们给得太低了。这样他们就会给下一个offer的人更高的薪资了。
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务