zoukankan      html  css  js  c++  java
  • [ Leetcode ] No.460 LFU缓存

    题目:
    请你为 最不经常使用(LFU)缓存算法设计并实现数据结构。它应该支持以下操作:get 和 put。

    get(key) - 如果键存在于缓存中,则获取键的值(总是正数),否则返回 -1。
    put(key, value) - 如果键不存在,请设置或插入值。当缓存达到其容量时,则应该在插入新项之前,使最不经常使用的项无效。在此问题中,当存在平局(即两个或更多个键具有相同使用频率)时,应该去除 最近 最少使用的键。
    「项的使用次数」就是自插入该项以来对其调用 get 和 put 函数的次数之和。使用次数会在对应项被移除后置为 0 。

    题解:
    这题其实不会做... 先记录 有机会重新写过

    struct Node {
        int key, val, fre;
        Node(int x, int y, int z): key(x), val(y), fre(z) {}
    };
    class LFUCache {
    public:
        int cap, minfreq;
        unordered_map<int, list<Node>::iterator> stuff;
        unordered_map<int, list<Node>> fre_table;
    
        LFUCache(int capacity) {
            cap = capacity;
            minfreq = 0;
            stuff.clear(); fre_table.clear();
        }
        
        int get(int key) {
            if(cap == 0) return -1;
            auto it = stuff.find(key);
            if (it == stuff.end()) return -1;
            // 有数值
            list<Node>::iterator node = it->second;
            int val = node->val, fre = node->fre;
            fre_table[fre].erase(node); //将该节点修改频率哈希表,应存入+1处
            if(fre_table[fre].size() == 0) {
                fre_table.erase(fre); //直接把链表删除
                if (minfreq == fre) minfreq += 1;
            }
            // 插入
            fre_table[fre + 1].push_front(Node(key, val, fre + 1));
            stuff[key] = fre_table[fre + 1].begin(); //新节点插入节点头
            return val;
        }
        
        void put(int key, int value) {
            if(cap == 0) return;
            auto it = stuff.find(key);
            if(it == stuff.end()) {
                if(stuff.size() == cap) { //缓存已满
                    auto it2 = fre_table[minfreq].back(); //旧在末尾
                    stuff.erase(it2.key);
                    fre_table[minfreq].pop_back();
                    if(fre_table[minfreq].size() == 0) fre_table.erase(minfreq);
                }
                fre_table[1].push_front(Node(key, value, 1));
                stuff[key] = fre_table[1].begin();
                minfreq = 1;
            } else {
                list<Node>::iterator node = it->second;
                int fre = node->fre;
                fre_table[fre].erase(node);
                if(fre_table[fre].size() == 0) {
                    fre_table.erase(fre);
                    if(minfreq == fre) minfreq += 1;
                }
                fre_table[fre + 1].push_front(Node(key, value, fre + 1));
                stuff[key] = fre_table[fre + 1].begin();
            }
        }
    };
    
    /**
     * Your LFUCache object will be instantiated and called as such:
     * LFUCache* obj = new LFUCache(capacity);
     * int param_1 = obj->get(key);
     * obj->put(key,value);
     */
    
  • 相关阅读:
    RabbitMQ管理
    vc6.0
    SystemTap
    undefined reference to `__imp_socket'
    采集小板校时
    点播播放不出来
    抓包注意事项
    下载rfc
    CLion快捷键
    rtsp vlc请求实例
  • 原文地址:https://www.cnblogs.com/recoverableTi/p/12641390.html
Copyright © 2011-2022 走看看