zoukankan      html  css  js  c++  java
  • [LeetCode] LRU Cache

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.

    get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
    put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

    Follow up:
    Could you do both operations in O(1) time complexity?

    Example:

    LRUCache cache = new LRUCache( 2 /* capacity */ );
    
    cache.put(1, 1);
    cache.put(2, 2);
    cache.get(1);       // returns 1
    cache.put(3, 3);    // evicts key 2
    cache.get(2);       // returns -1 (not found)
    cache.put(4, 4);    // evicts key 1
    cache.get(1);       // returns -1 (not found)
    cache.get(3);       // returns 3
    cache.get(4);       // returns 4
    使用list来维持一个list双向链表。
    使用map来保存链表值及链表中该值对应的迭代器。
    update()函数用来调整list中的元素位置。
    get()来获取list中的元素值
    put()将元素放入list中。
     
    class LRUCache {
    public:
        LRUCache(int capacity) : capacity(capacity){
        
        }
        
        int get(int key) {
            auto it = cache.find(key);
            // key exists.
            if (it != cache.end())
            {
                return update(it->second);
            }
            // key does not exist.
            return -1;
        }
        
        void put(int key, int value) {
            auto it = cache.find(key);
            // key exists
            if (it != cache.end())
            {
                // set new value.
                it->second->second = value;
                // update to MRU element.
                update(it->second);
            }
            // key does not exist.
            else
            {
                // cache is full. evict LRU element.
                if (data.size() >= capacity)
                {
                    // delete LRU element from list.
                    pair<int, int> p = data.back();
                    data.pop_back();
                    // remove cache entry.
                    cache.erase(p.first);
                }
                // add element to the front of the list.
                data.push_front({key, value});
                // add element to the cache.
                cache[key] = data.begin();
            }
        }
    private:
        // updates the position of an element to the front of the list.
        // by removing the old position from the list and updating the cache.
        int update(list<pair<int, int>>::iterator& it) {
            int key = it->first;
            int value = it->second;
            data.erase(it);
            data.push_front({key, value});
            cache[key] = data.begin();
            return value;
        }
    private:
        // capacity.
        int capacity;
        // cache: {key, iterator to list element}
        unordered_map<int, list<pair<int, int>>::iterator> cache;
        // data: {key, value}
        list<pair<int, int>> data;
    };
    
    /**
     * 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);
     */
  • 相关阅读:
    Checking Types Against the Real World in TypeScript
    nexus pip proxy config
    go.rice 强大灵活的golang 静态资源嵌入包
    几个golang 静态资源嵌入包
    rpm 子包创建学习
    Rpm Creating Subpackages
    ava 类似jest snapshot 功能试用
    ava js 测试框架基本试用
    The Architectural Principles Behind Vrbo’s GraphQL Implementation
    graphql-compose graphql schema 生成工具集
  • 原文地址:https://www.cnblogs.com/immjc/p/9201398.html
Copyright © 2011-2022 走看看