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  */

 

posted @ 2020-07-21 16:14  __rookie  阅读(133)  评论(0编辑  收藏  举报