leetcode-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.

题意:完成一个LRU缓存类,存储<key,value>映射表,具体功能为,初始化读入一个缓存大小capacity,之后又set和get两种操作:

get(key):得到对应key的value,若key不存在,返回-1

set(key):将key的值设为value,若缓存数据超过规定大小capacity,舍弃更新时间最远的数据,加入新数据。

注意:set和get对key的操作都算作对key的更新

分析:用一个map存储数据映射表mp,之后的难点在于,需要一个数据结构,将所有key按照更新时间排序,能够在O(1)找到最久远的(队头的)key并删除且能在O(1)找到任意一个key并放到队尾,并将置为最新,即把它放到队尾。考虑过用set或者链表,但都不能解决问题。后来想到一种用两个map记录的方法,如下:

1、将所有key按更新时间组成一个“链表”,表头为最旧key,表尾为最新的key

2、用map<int,int> next,pre; 分别记录“链表”中key的前驱和后继,用lastkey和newkey记录表头和表尾。

3、每次set和get,只要操作的key在数据表mp中,更新key在链表中的位置,将其放到表尾,并更新对应的next和pre值,将newkey置为当前的key

4、若set时达到capacity,删除lastkey,更新链表,并从数据表mp中删除

这样,插入,更改,删除的复杂度均为O(1)。

代码:

class LRUCache{
private:
    map<int,int> mp;
    int cap;
    map<int,int> next,pre;
    int lastkey,newkey;
    
    void update(int key)
    {
        if(newkey<0)
        {
            newkey = lastkey = key;
            return;
        }
        
        if(next.find(key)!=next.end())
        {
            int nxt = next[key];
            if(pre.find(key)!=pre.end())
            {
                int pr = pre[key];
                next[pr] = nxt;
                pre[nxt] = pr;
            }
            else
            {
                lastkey = nxt;
                pre.erase(nxt);
            }
            
            next.erase(key);
        }
        if(newkey!=key)
        {
            next[newkey] = key;
            pre[key] = newkey;
            newkey = key;
        }
    }
    void del()
    {
        if(next.find(lastkey)!=next.end())
        {
            int nxt = next[lastkey];
            next.erase(lastkey);
            pre.erase(nxt);
            lastkey = nxt;
        }
        else
        {
            lastkey = newkey = -1;
        }
    }
public:
    LRUCache(int capacity) {
        cap = capacity;
        lastkey = newkey = -1;
    }
    
    int get(int key) {
        if(mp.find(key)!=mp.end())
        {
            update(key);
            return mp[key];
        }
        return -1;
    }
    
    void set(int key, int value) {
        update(key);
        if(mp.find(key)==mp.end() && mp.size()==cap)
        {
            if(lastkey>0)
                mp.erase(lastkey);
            del();
        }
        mp[key] = value;
    }
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章