• [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);
     */
  • 相关阅读:
    PAT甲级1114. Family Property
    PAT甲级1111. Online Map
    Android零基础入门第84节:引入Fragment原来是这么回事
    Android零基础入门第83节:Activity间数据传递方法汇总
    Android零基础入门第82节:Activity数据回传
    Android零基础入门第81节:Activity数据传递
    Android零基础入门第80节:Intent 属性详解(下)
    Android零基础入门第79节:Intent 属性详解(上)
    Android零基础入门第78节:四大组件的纽带——Intent
    Android零基础入门第77节:Activity任务栈和启动模式
  • 原文地址:https://www.cnblogs.com/immjc/p/9201398.html
Copyright © 2020-2023  润新知