Skip to content

M146.LRU缓存

hash table, doubly-linked list, https://leetcode.cn/problems/lru-cache/

思路:先自己写一个链表,用字典存储键值和其对应的地址,然后完成函数即可,加上学习,用时约30min

cpp
struct Listnode
{
    int key, value;
    Listnode* next, * prev;
    Listnode(int k, int v) :key(k), value(v), next(NULL), prev(NULL) {}
    Listnode() :key(0), value(0), next(NULL), prev(NULL) {}
};

class LRUCache 
{
private:
    unordered_map<int, Listnode*> map;
    Listnode* head, * tail;
    int capacity, size;
public:
    
    LRUCache(int capacity)
    {
        this->capacity = capacity;
        this->size = 0;
        head = new Listnode();//伪头节点
        tail = new Listnode();
        head->next = tail;
        tail->prev = head;
    }

    int get(int key)
    {
        if (map.find(key) == map.end())
            return -1;
        Listnode* node = map[key];
        toHead(node);
        return node->value;
    }

    void put(int key, int value)
    {
        if (map.find(key) == map.end())//不存在
        {
            Listnode* node = new Listnode(key, value);
            map[key] = node;
            addNodeToHead(node);
            size++;
            if (size > capacity)//超出容量
            {
                map.erase(tail->prev->key);
                removeTail();
                size--;
            }
        }
        else//存在
        {
            Listnode* node = map[key];
            node->value = value;
            toHead(node);
        }
    }

    void removeNode(Listnode* node)
    {
        node->prev->next = node->next;
        node->next->prev = node->prev;
    }

    void addNodeToHead(Listnode* node)
    {
        node->prev = head;
        node->next = head->next;
        head->next->prev = node;
        head->next = node;
    }

    void toHead(Listnode* node)
    {
        removeNode(node);
        addNodeToHead(node);
    }

    void removeTail()
    {
        Listnode* node = tail->prev;
        removeNode(node);
    }
};
cpp
class LRUCache {
public:
    int cap,sz=0;
    list<int> l;
    int mp[100005], pos[100005], cnt[100005];
    LRUCache(int capacity) {
        cap=capacity;
        memset(mp,-1,sizeof(mp));
    }
    
    int get(int key) {
        if(mp[key]!=-1) {
            l.push_back(key);
            cnt[key]++;
        }
        return mp[key];
    }
    
    void put(int key, int value) {
        if(mp[key]!=-1) {
            mp[key]=value;
            cnt[key]++;
            l.push_back(key);
        }else {
            sz++;
            mp[key]=value;
            cnt[key]++;
            l.push_back(key);
            while(sz>cap) {
                if(--cnt[l.front()]==0) {
                    mp[l.front()]=-1;
                    sz--;
                }
                l.pop_front();
            }
        }
    }
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */