【leetcode】LRU Cache(hard)★

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

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(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.

 

思路:

这题吧,思路挺清楚的,就是每次get, set时都把对应的数据设为时间最近的数据,如果满了,就在set时把最老的数据扔掉,把新的插入到最近的位置。

关键是,如何在O(1)的时间内get到所需的数据,如何在O(1)的时间内,找到最老的数据。

第一个问题可以用unordered_map轻松解决,但是,第二个问题我就不会了。我很low的用了遍历,果断超时了。看答案后发现,要用list的splice函数解决。

把所有的数据按照访问时间由近到远存放在一个list中,当再次访问里面的数据时,就把该数据移动到list的开始位置,满了后就移除list的最后一个元素。

上大神的答案:

class LRUCache {

private:

    // A list of (key, value) pairs

    list<pair<int, int>> items;

    // Map items to iterators (pointers) to list nodes

    unordered_map<int, list<pair<int, int>>::iterator> cache;

    // The capacity of the list

    int capacity;



public:

    LRUCache(int capacity) : capacity(capacity) {}



    int get(int key) {

        // If key is not found in hash map, return -1

        if (cache.find(key) == cache.end())

            return -1;

        // Move the (key, value) pair to the beginning of the list

        items.splice(items.begin(), items, cache[key]);

        return cache[key]->second;

    }



    void set(int key, int value) {

        // The key is not in the hash table

        if (cache.find(key) == cache.end()) {

            // If the cache is full then delete the least recently

            // used item, which is at the end of the list

            if (items.size() == capacity) {

                cache.erase(items.back().first);

                items.pop_back();

            }

            items.push_front(make_pair(key, value));

            cache[key] = items.begin();

        } else {

            // Update the value associated with the key

            cache[key]->second = value;

            // Move the (key, value) pair to the beginning of the list

            items.splice(items.begin(), items, cache[key]);

        }

    }

}

 

 

我的代码,时间是用自己设的time来记录的,超时了。

typedef struct Data

{

    int value;

    int time;

    Data(){}

    Data(int v, int t) : value(v), time(t){}

}Data;



class LRUCache{

public:

    LRUCache(int capacity) {

        t = 0;                //初始化时间

        c = capacity;         //初始化容量

    }

    

    int get(int key) {

        unordered_map<int, Data>::iterator it = record.find(key);

        if(it == record.end())

        {

            return -1;

        }

        else

        {

            it->second.time = t++;

            return it->second.value;

        }



    }

    

    void set(int key, int value) {

        if(record.find(key) != record.end())

        {

            record[key].value = value;

            record[key].time = t++;

            return;

        }

        if(record.size() == c)   //容量已经达到

        {

            unordered_map<int, Data>::iterator replace = record.begin();

            for(unordered_map<int, Data>::iterator it = record.begin(); it != record.end(); it++)

            {

                replace = (it->second.time < replace->second.time) ? it : replace;

            }

            record.erase(replace); //删掉时间最早的

        }



        Data newData(value, t);

        record[key] = newData;

        t++;

    }

private:

    unordered_map<int, Data> record;

    int c;

    int t;

};

 

你可能感兴趣的:(LeetCode)