460. LFU缓存

460. LFU缓存

有一个疑问,当我的构造函数这个样定义的时候

Node(int _cnt, int _time, int _key, int _value) {
        cnt = _cnt;
        time = _time;
        key = _key;
        value = _value;
    }

我这样调用unordered_map是不会通过编译 

int get(int key) {
        if(capacity == 0) {
            return -1;
        }

        auto it = key_value.find(key);
        if(it == key_value.end()) {
            return -1;
        }

        Node cache = key_value[key]; // 这一行不能通过编译,cache通过it->second却是能够正常赋值的

        s.erase(cache);
        cache.cnt++;
        cache.time = ++time;
        s.insert(cache);
        it->second = cache;

        return cache.value;
    }

 

但是,当我构造函数这个样定义的时候


  Node(){}
     Node(int _cnt, int _time, int _key, int _value) {
         cnt = _cnt;
         time = _time;
         key = _key;
         value = _value;
     }

 

 Node cache = key_value[key]; 

 

却能够正确编译,记录一下

 

代码:

 1 struct Node {
 2     int cnt;
 3     int time;
 4     int key, value;
 5     
 6     Node(){}
 7     Node(int _cnt, int _time, int _key, int _value) {
 8         cnt = _cnt;
 9         time = _time;
10         key = _key;
11         value = _value;
12     }
13 
14     bool operator < (const Node& t) const {
15         return t.cnt == cnt ? time < t.time: cnt < t.cnt; 
16     }
17 };
18 
19 class LFUCache {
20     int time;
21     unordered_map<int, Node> key_value;
22     set<Node> s;
23     int capacity;
24 public:
25     LFUCache(int _capacity) {
26         key_value.clear();
27         time = 0;
28         s.clear();
29         capacity = _capacity;
30     }
31     
32     int get(int key) {
33         if(capacity == 0) {
34             return -1;
35         }
36 
37         auto it = key_value.find(key);
38         if(it == key_value.end()) {
39             return -1;
40         }
41         Node cache = key_value[key];
42         s.erase(cache);
43         cache.cnt++;
44         cache.time = ++time;
45         s.insert(cache);
46         it->second = cache;
47 
48         return cache.value;
49     }
50     
51     void put(int key, int value) {
52         if(capacity == 0) {
53             return ;
54         }
55 
56         auto it = key_value.find(key);
57 
58         if(it == key_value.end()) {
59             if(key_value.size() == capacity) {
60                 key_value.erase(s.begin()->key);
61                 s.erase(s.begin());
62             }
63 
64                 Node node = Node(1, ++time, key, value);
65                 key_value.insert(make_pair(key, node));
66                 s.insert(node);
67             
68         }
69         else {
70             Node tmp = key_value[key];
71             s.erase(tmp);
72             tmp.cnt += 1;
73             tmp.time = ++time;
74             tmp.value = value;
75             it->second = tmp;
76             s.insert(tmp);
77         }
78 
79     }
80 };
81 
82 /**
83  * Your LFUCache object will be instantiated and called as such:
84  * LFUCache* obj = new LFUCache(capacity);
85  * int param_1 = obj->get(key);
86  * obj->put(key,value);
87  */

 方法二:

每一个频率创建一个链表,然后还有一个unordered_map用作定位

struct Node {
    int key;
    int val;
    int freq;
    Node(){}
    Node(int _key, int _val, int _freq) {
        key = _key;
        val = _val;
        freq = _freq;
    }
};

class LFUCache {
    unordered_map<int, list<Node> > key_to_freq;
    unordered_map<int, list<Node>::iterator> key_to_value;
    int capacity;
    int minfreq;

public:
    LFUCache(int _capacity) {
        capacity = _capacity;
        key_to_freq.clear();
        key_to_value.clear();
        minfreq = 0;
    }
    
    int get(int key) {
        if(capacity == 0) {
            return -1;
        }
        auto iter = key_to_value.find(key);
        if(iter == key_to_value.end()) {
            return -1;
        }
        else {
            list<Node>::iterator pos = iter->second;
            int freq = pos->freq, val = pos->val;
            key_to_freq[freq].erase(pos);

            if(key_to_freq[freq].size() == 0) {
                key_to_freq.erase(freq);
                if(freq == minfreq) {
                    minfreq += 1;
                }
            }
            
            key_to_freq[freq + 1].push_front(Node(key, val, freq + 1));
            key_to_value[key] = key_to_freq[freq + 1].begin();
            return val;
        }
    }
    
    void put(int key, int value) {
        if(capacity == 0) {
            return ;
        }
        auto iter = key_to_value.find(key);
        if(iter != key_to_value.end()) {
            list<Node>::iterator pos = iter->second;
            int freq = pos->freq, val = pos->val;
            key_to_freq[freq].erase(pos);
            key_to_value.erase(key);

            if(key_to_freq[freq].size() == 0) {
                key_to_freq.erase(freq);
                if(freq == minfreq) {
                    minfreq += 1;
                }
            }

            key_to_freq[freq + 1].push_front(Node(key, value, freq + 1));
            key_to_value[key] = key_to_freq[freq + 1].begin();
            

            return ;
        }
        else {
            if(key_to_value.size() == capacity) {
                Node pos = key_to_freq[minfreq].back();
                int  val = pos.val, freq = pos.freq;
                key_to_value.erase(pos.key);
                key_to_freq[minfreq].pop_back();
                if(key_to_freq[minfreq].size() == 0) {
                    key_to_freq.erase(minfreq);
                }
            }

            //Node node = new Node(key, value, 1);
            key_to_freq[1].push_front(Node(key, value, 1));
            key_to_value[key] = key_to_freq[1].begin();
            minfreq = 1;
        } 
        return ;
    }
};

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

 

 

posted @ 2020-04-20 14:34  Let_Life_Stop  阅读(147)  评论(0编辑  收藏  举报