首页 > 其他分享 >Leetcode——双向链表和哈希表实现LRU缓存和LFU缓存

Leetcode——双向链表和哈希表实现LRU缓存和LFU缓存

时间:2023-01-14 17:44:06浏览次数:72  
标签:node LFU pre 缓存 DoublelyLinkedList int value 链表 key

一、Leetcode146.LRU缓存

1. 使用STL list和unordered_map实现

using KV  = pair<int, int>;
class LRUCache{
private:
    int cacheCapacity;
    list<KV> cacheList;
    unordered_map<int, list<KV>::iterator> keyToIter;
public:
    LRUCache(int capacity) {
        cacheCapacity = capacity;
    }

    int get(int key) {
        int value = -1;
        if(keyToIter.count(key)){
            value = keyToIter[key]->second;
            update(key, value);
        }
        return value;
    }

    void put(int key, int value) {
        if(keyToIter.count(key)){
            update(key, value);
        }else{
            add(key, value);
        }
    }

    void update(int key, int value){
        auto iter = keyToIter[key];
        cacheList.erase(iter);
        cacheList.emplace_front(key, value);
        keyToIter[key] = cacheList.begin();
    }

    void add(int key, int value){
        if(cacheList.size() == cacheCapacity){
            keyToIter.erase(cacheList.back().first);
            cacheList.pop_back();
        }
        cacheList.emplace_front(key, value);
        keyToIter[key] = cacheList.begin();
    }
};

2.自己实现一个双向链表实现

struct DoublelyLinkedList{
    int key;
    int val;
    DoublelyLinkedList* pre;
    DoublelyLinkedList* next;
    DoublelyLinkedList(int key, int val): key(key), val(val){};
    DoublelyLinkedList(): key(0), val(0){};
};
class LRUCache {
private:
    int cacheCapacity;
    int size;
    unordered_map<int, DoublelyLinkedList*> keyToNode;
    DoublelyLinkedList* head;
    DoublelyLinkedList* tail;
public:
    LRUCache(int capacity) {
        cacheCapacity = capacity;
        head = new DoublelyLinkedList();
        tail = new DoublelyLinkedList();
        size = 0;
        head->next = tail;
        tail->pre = head;
    }
    int get(int key) {
        int value = -1;
        if(keyToNode.count(key)){
            value = keyToNode[key]->val;
            update(key, value);
        }
        return value;
    }

    void put(int key, int value) {
        if(keyToNode.count(key)){
            update(key, value);
        }else{
            add(key, value);
        }
    }

    void update(int key, int value){
        auto node = keyToNode[key];
        node->val = value;
        erase_node(node);
        push_front(node);
    }

    void add(int key, int value){
        if(size == cacheCapacity){
            keyToNode.erase(tail->pre->key);
            erase_node(tail->pre);
            size--;
        }
        size++;
        auto newNode = new DoublelyLinkedList(key, value);
        push_front(newNode);
        keyToNode[key] = newNode;
    }

    void push_front(DoublelyLinkedList* node){
        node->pre = head;
        node->next = head->next;
        head->next->pre = node;
        head->next = node;
    }
    
    void erase_node(DoublelyLinkedList* node){
        node->pre->next = node->next;
        node->next->pre = node->pre;
    }

};

二、Leetcode460.LFU 缓存

标签:node,LFU,pre,缓存,DoublelyLinkedList,int,value,链表,key
From: https://www.cnblogs.com/qiangz/p/15853660.html

相关文章