---
# System prepended metadata

title: Algo｜LRU/LFU Cache 設計
tags: [Algo]

---

# LRU/LFU Cache 設計
- [146. LRU Cache](https://leetcode.com/problems/lru-cache/)
    - 維護最近用過的 list: `3<-8<-5<-6`
        - Insert(6) : `6<-3<-8<-5`
        - Insert(4) : `4<-6<-3<-8`
    ```c++=
    class LRUCache {
        int CAP;
        list<int> l;
        unordered_map<int, pair<list<int>::iterator, int>> mp;
    public:
        LRUCache(int capacity) {
            ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
            CAP = capacity;
        }

        int get(int key) {
            if(mp.count(key)==0)    return -1;

            l.push_front(key);
            l.erase(mp[key].first);   
            mp[key].first = l.begin();
            return mp[key].second;
        }

        void put(int key, int value) {
            if(get(key)!=-1){
                mp[key].second = value;
            }else{
                if(l.size() == CAP){
                    mp.erase(l.back());
                    l.pop_back();
                }
                l.push_front(key);
                mp[key] = {l.begin(), value};
            }
        }
    };
    ```
- [460. LFU Cache](https://leetcode.com/problems/lfu-cache/submissions/)
    - 維護每個頻率的 list: `1: 3<-8`, `2:5<-6`
        - Insert(4) : `1: 8<-4`, `2:5<-6`
        - Insert(8) : `1: 4`, `2:5<-6<-8`
    - 需要 2 個 map
        - frequency -> list
        - key -> (value, frequency, list position)
    ```c++=
    struct node{
        int value, freq;
        list<int>::iterator it;
    };


    class LFUCache {    
        int CAP, minF;
        unordered_map<int, node> mp;
        unordered_map<int, list<int>> data;
    public:
        LFUCache(int capacity) {
            ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
            CAP = capacity;
            minF = 1;
        }

        int get(int key) {
            if(mp.count(key)==0)    return -1;

            data[mp[key].freq].erase(mp[key].it);
            mp[key].freq++;
            data[mp[key].freq].push_back(key);
            mp[key].it = prev( data[mp[key].freq].end());
            if(data[minF].size()==0)    minF++;
            return mp[key].value;
        }

        void put(int key, int value) {
            if(CAP==0)  return;

            if(get(key)!=-1){
                mp[key].value = value;
            }else{
                if(mp.size() == CAP){
                    mp.erase(data[minF].front());
                    data[minF].pop_front();
                }
                data[1].push_back(key);
                mp[key] = {value, 1, prev(data[1].end())};
                minF = 1;
            }
        }
    };
    ```
    
