LRU Cache

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.

分析:

超时版本,用list作底层数据结构:

class LRUCache{
private:
    list<pair<int,int>> cache;
    int capacity;
    int size;
    list<pair<int,int>>::iterator myfind(int key){
        for(auto i = cache.begin(); i != cache.end(); i++)
            if(i->first == key) return i;
        return cache.end();
    }
public:
    LRUCache(int capacity) {
        this->capacity = capacity;
        size = 0;
    }
    
    int get(int key) {
        if(size == 0) return -1;
        list<pair<int,int>>::iterator p;
        if((p = myfind(key)) != cache.end()){
            pair<int,int> tmp = *p;
            cache.erase(p);
            cache.push_front(tmp);
            return tmp.second;
        }else return -1;
    }
    
    void set(int key, int value) {
        list<pair<int,int>>::iterator p;
        if(size == 0 || (p = myfind(key)) == cache.end()){
            if(size == capacity){
                cache.pop_back();
                size--;
            }
            cache.push_front(make_pair(key, value));
            size++;
        }else{
            p->second = value;
            cache.push_front(*p);
            cache.erase(p);
        }
    }
};

 上面的代码在查找时很费时,为了使减少查找时间,可以用unordered_map存储现有的key值和对应的list的迭代器,代码如下:

class LRUCache{
private:
    list<pair<int,int>> cache;
    unordered_map<int, list<pair<int,int>>::iterator> key_map;
    int capacity;
    int size;
public:
    LRUCache(int capacity) {
        this->capacity = capacity;
        size = 0;
    }
    
    int get(int key) {
        if(size == 0) return -1;
        unordered_map<int, list<pair<int,int>>::iterator>::iterator p;
        if((p = key_map.find(key)) != key_map.end()){
            pair<int,int> tmp = *(p->second);
            cache.erase(p->second);
            cache.push_front(tmp);
            key_map[key] = cache.begin();
            return tmp.second;
        }else return -1;
    }
    
    void set(int key, int value) {
        unordered_map<int, list<pair<int,int>>::iterator>::iterator p = key_map.find(key);
        if(size == 0 || p == key_map.end()){
            if(size == capacity){
                key_map.erase(cache.back().first);
                cache.pop_back();
                size--;
            }
            cache.push_front(make_pair(key, value));
            size++;
        }else{
            p->second->second = value;
            cache.push_front(*(p->second));
            cache.erase(p->second);
        }
        key_map[key] = cache.begin();
    }
};

 

posted on 2014-10-25 20:31  Ryan-Xing  阅读(172)  评论(0编辑  收藏  举报