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;
    }
};


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