• LeetCode460 LFU缓存


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

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

    这题和LRU类似,但是多了一个使用频率的问题。可以通过相同的思路,但是增加一个哈希表的方式来解决。但是也可以直接依靠set的自动排序特点来解决。

    关于如何给set或者map设置比较函数,来给自己定义的结构类型排序,可以参考这篇文章:https://blog.csdn.net/weixin_40237626/article/details/80511572

    总之用一个哈希表来存储key对应的结构体,再把这些结构体插入到set中。根据set的自动排序特征就可以实现在o(1)时间内找到应该删除的元素。

     1 struct Node{
     2     int key;
     3     int value;
     4     int latest_time;
     5     int frequecy;
     6     Node(int _key, int _value, int _latest_time, int _frequency):key(_key),value(_value),latest_time(_latest_time),frequecy(_frequency){
     7     }
     8     bool operator< (const Node& comp) const{
     9         return frequecy==comp.frequecy?latest_time<comp.latest_time:frequecy<comp.frequecy;
    10     }
    11 
    12 };
    13 
    14 class LFUCache {
    15 private:
    16     int capacity;
    17     int cur_time;
    18     unordered_map<int,Node> key_table;
    19     set<Node> sNode;
    20 public:
    21     LFUCache(int _capacity) {
    22         capacity=_capacity;
    23         cur_time=0;
    24         key_table.clear();
    25         sNode.clear();
    26     }
    27     
    28     int get(int key) {
    29         if(capacity==0)
    30             return -1;
    31         auto it=key_table.find(key);
    32         if(it==key_table.end())
    33             return -1;
    34         Node cache=it->second;
    35         sNode.erase(cache);
    36         ++cache.frequecy;
    37         cache.latest_time=++cur_time;
    38         sNode.insert(cache);
    39         it->second=cache;
    40         return cache.value;
    41 
    42     }
    43     
    44     void put(int key, int value) {
    45         if(capacity==0)
    46             return;
    47         auto it=key_table.find(key);
    48         if(it!=key_table.end()){
    49             Node cache=it->second;
    50             sNode.erase(cache);
    51             ++cache.frequecy;
    52             cache.value=value;
    53             cache.latest_time=++cur_time;
    54             sNode.insert(cache);
    55             it->second=cache;
    56         }
    57         else{
    58             if(key_table.size()==capacity){
    59                 key_table.erase(sNode.begin()->key);
    60                 sNode.erase(sNode.begin());
    61             }
    62             Node cache=Node(key,value,++cur_time,1);
    63             sNode.insert(cache);
    64             key_table.insert(make_pair(key,cache));
    65         }
    66     }
    67 };
    68 
    69 /**
    70  * Your LFUCache object will be instantiated and called as such:
    71  * LFUCache* obj = new LFUCache(capacity);
    72  * int param_1 = obj->get(key);
    73  * obj->put(key,value);
    74  */
  • 相关阅读:
    不同的ospf进程发布互联网段可以互通
    大数分解
    主席树(非权值)
    块状数组
    Codeforces Round #744 (Div. 3) G. Minimal Coverage
    记录一种从天而降的掌法(动态维护中位数的方法)
    快速统计二进制中1的数量
    网络流(小常数)
    矩阵快速幂
    米勒罗宾素性检验
  • 原文地址:https://www.cnblogs.com/rookiez/p/13355702.html
Copyright © 2020-2023  润新知